drilow
drilow

Reputation: 412

Proper way to null check in Expression-Tree lambda

First of all, I want to excuse myself for posting a similar question to other existing ones, but I am new to C#, and only starting to grasp LINQ. I have some business logic across two tables that gets a field of a row. If no such row exists, it should just default to an empty String. Outside LINQ this would be easy:

var res = SomeClass.foo?.bar ?? "";

But in LINQ the operators ?. and ?? are not supported, so I resorted to this:

     var projectTask = repository.Set<tblProject>().Where(p => includeInactive ||
                            (p.tblOrderStatus.OrderByDescending(s => s.Date).FirstOrDefault().StatusID != StatusIds.Deducted &&
                            p.tblOrderStatus.OrderByDescending(s => s.Date).FirstOrDefault().StatusID != StatusIds.Deduc_RestDecays &&
                            p.tblOrderStatus.OrderByDescending(s => s.Date).FirstOrDefault().StatusID != StatusIds.Cancelled))
                            .Select(p => new {
                                p.ID,
                                p.CustomerID,
                                p.CenterID,
                                p.FrameworkID,
                                p.DeductionmodeID,
                                p.Code,
                                p.Descriptioln,
                                p.StartDate,
                                p.EndDate,
                                Referencetext = p.tblOrderHistories.Where(m => m.OrderReferencetypeID == 1).OrderByDescending(m => m.Date).FirstOrDefault() != null ?
                                p.tblOrderHistories.Where(m => m.OrderReferencetypeID == 1).OrderByDescending(m => m.Date).FirstOrDefault().Referencetext : ""
                            })
                            .ToListAsync();

Where I do the Query twice, which isn't performance killing in this case, but still not very elegant.

I understand you can construct LINQ expressions through Expression, but I can't quite find an example of my case.

Thank you in advance.

Upvotes: 1

Views: 400

Answers (1)

Ivan Stoev
Ivan Stoev

Reputation: 205629

But in LINQ the operators ?. and ?? are not supported

I guess by LINQ here you mean LINQ against IQueryable (inside expression trees) because in LINQ against IEnumerable (with delegates) both are supported.

While you are right that ?. operator is not supported in the expression trees (yet), the ?? is perfectly supported.

So if the question is for this expression:

Referencetext = 
    p.tblOrderHistories.Where(m => m.OrderReferencetypeID == 1)
        .OrderByDescending(m => m.Date).FirstOrDefault() != null ?
    p.tblOrderHistories.Where(m => m.OrderReferencetypeID == 1)
        .OrderByDescending(m => m.Date).FirstOrDefault().Referencetext : ""

it can easily be handled with combination of Select, FirstOrDefault and ?? operator:

Referencetext = p.tblOrderHistories
    .Where(m => m.OrderReferencetypeID == 1)
    .OrderByDescending(m => m.Date)
    .Select(m => m.Referencetext)
    .FirstOrDefault() ?? ""

Upvotes: 2

Related Questions