Link to home
Start Free TrialLog in
Avatar of Tom Knowlton
Tom KnowltonFlag for United States of America

asked on

LINQ syntax - where condition?

decimal dec = Convert.ToDecimal(_repairBids.Select(o => o.BidAmt == null ? 0 : o.BidAmt).Sum(o => o));


if I wanted to filter this by "o.Status = "Approved" so that only bid amounts that are approved get totalled...what would be the syntax?
Avatar of p_davis
p_davis

decimal dec = Convert.ToDecimal(_repairBids.Where(o.Status == "Approved").Select(o => o.BidAmt == null ? 0 : o.BidAmt).Sum(o => o));
Avatar of Tom Knowlton

ASKER

That looks correct to me.

If you don't mind helping me out, I keep getting:

value cannot be null

I tried to make provisions for this by adding this:

o.BidAmt == null ? 0 : o.BidAmt

but I must either be doing that wrong or the problem is elsewhere...


decimal dec = Convert.ToDecimal(_repairBids.Where(o => o.BidStatus == "Approved").Select(o => o.BidAmt == null ? 0 : o.BidAmt).Sum(o => o));

Open in new window



User generated image
Does this make sense?


decimal dec = Convert.ToDecimal(_repairBids.Where(o => o.BidStatus == "Approved").Where(o => o.BidAmt != null).Select(o => o.BidAmt).Sum(o => o));


can you do multiple "WHERE"'s like that?
do you know what is actually null?

you can try to check every level of that  object for null

o=> o == null  && ....?

also is it possible that the bidstatus is null? you might want to check for null in the where clause as well.
you can combine those two where clauses into one with &&
null means "has never had a value" right?

[EDIT]

In other words, null is not 0, "0" or ""
I thought BidAmt was a string? You can't mix types when using the conditional operator. Change the zero to a string:

decimal dec = Convert.ToDecimal(_repairBids.Where(o.Status == "Approved").Select(o => o.BidAmt == null ? "0" : o.BidAmt).Sum(o => o));

Open in new window

>>  also is it possible that the bidstatus is null?

I supposed it could happen.  Better to be safe.  I'll check on that...
>>>>I thought BidAmt was a string? You can't mix types when using the conditional operator. >>>>Change the zero to a string:


in one result it WAS indeed a string.


in another it is an actual decimal.


Let me recheck that....
This line compiles fine, but at runtime I still get the error:  value cannot be null

decimal dec = Convert.ToDecimal(_repairBids.Where(o => o.BidStatus == "Approved" && o.BidStatus != null && o.BidAmt != null).Select(o => o.BidAmt).Sum(o => o));

Open in new window



What am I missing?
For readability's sake, I'd suggest breaking that logic up a bit (once the issue is corrected):

decimal dec;

var sum = _repairBids.Where(o.Status == "Approved")
                     .Select(o => o.BidAmt ?? "0")
                     .Sum(o => o);

dec = Convert.ToDecimal(sum);

Open in new window

Does it matter where the WHERE is called in the chain?

For example, does it matter if the WHERE is before the SELECT in LINQ?
It can matter, but I don't think it does in this case.

What is the type of BidAmt?
>>>What is the type of BidAmt?


It is:

decimal?

which I interpret to mean it can be a decimal value or a null value returned
NOTE:

The exception message, if it helps at all:

System.ArgumentNullException was unhandled by user code
  Message=Value cannot be null.
Parameter name: source
  Source=System.Core
  ParamName=source
  StackTrace:
       at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate)
       at Reo.ContentControls.RepairBidFormSummary.ReturnTot() in C:\R13\Reo\ContentControls\RepairBidFormSummary.ascx.cs:line 81
       at Reo.ContentControls.Preservation.FillRepairBid() in C:\R13\Reo\ContentControls\Preservation.ascx.cs:line 266
       at Reo.ContentControls.Preservation.FillPg() in C:\R13\Reo\ContentControls\Preservation.ascx.cs:line 113
       at Reo.ContentControls.Preservation.Page_Load(Object sender, EventArgs e) in C:\R13\Reo\ContentControls\Preservation.ascx.cs:line 68
       at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
       at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
       at System.Web.UI.Control.OnLoad(EventArgs e)
       at System.Web.UI.Control.LoadRecursive()
       at System.Web.UI.Control.LoadRecursive()
       at System.Web.UI.Control.LoadRecursive()
       at System.Web.UI.Control.LoadRecursive()
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
  InnerException: 

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of kaufmed
kaufmed
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>>Are you certain that _repairBids is not null when you get to that line?

Good news!!

Yes...this was the case.  _repairBids was null.  The entire thing.

I guess I didn't realize I needed to re-get everything from the data context.


Here is my final code:


 public decimal ReturnTot()
        {
            decimal dec = 0;

            using (PreservationDataContext dc = new PreservationDataContext())
            {
                _repairBids = dc.Pres_RepairBidFormSummary_Get(this.RepairBidFormID, this.RepairBidFormSID).ToList<Pres_RepairBidFormSummary_GetResult>();

                if (_repairBids != null)
                {
                    dec = Convert.ToDecimal(_repairBids.Where(o => o.BidStatus == "Approved" && o.BidStatus != null && o.BidAmt != null).Select(o => o.BidAmt).Sum(o => o));
                }
            }
            
            return dec;            
        }

Open in new window

Nice work, all of you!