Is there a better way of writing this Linq Query

落爺英雄遲暮 提交于 2019-12-11 04:12:36

问题


Example

from O in db.Orders
join C in db.Customers on C.Id equals O.CustID
Where O.ord_date == ( filter.OrderDate != null ? filter.OrderDate : o.ord_date) &&
  c.Id == (filter.CustId != null ? filter.CustId : c.Id) &&
  o.ProductId == ( filter.ProductId != null ? filter.ProductId : o.ProductID)
select new {o,c}

//select new {c.Name, C.JoinDate, O.Value, O.NoofLineItems }

When i trun on the profile it has a lot of case statements as i expect it to have. but i have lot more control on the condition what i put in in C# how can i exersise my control on the where condition and only put the where condition when filter is available for it

This will improve my quality of sql which goes to the db.

Kind regards Vinay.


回答1:


A general solution for this sort of issue is to use PredicateBuilder to dynamically construct the appropriate predicate.

First, build the predicate:

Expression<Func<Order, bool>> predicate = PredicateBuilder.True<Order>();

if (filter.OrderDate != null)
    predicate = predicate.And(o => o.ord_date == filter.OrderDate);

if (filter.CustId != null)
    predicate = predicate.And(o => o.CustId == filter.CustId);

...

And then you query becomes:

var filtered = db.Orders.Where(predicate);

var query = from O in filtered 
            join C in db.Customers on C.Id equals O.CustID
            select new {o,c};      



回答2:


Given that the conditions do not depend on the query, you could have the conditionals out of the query and build it gradually:

var query = from o in db.Orders
            join c in db.Customers on c.Id equals o.CustID
            select new {o,c};
if(filter.OrderDate != null)
{
    query = query.Where(x => x.o.ord_date == filter.OrderDate);
}
if(filter.CustId != null)
{
    query = query.Where(x => x.c.Id == filter.CustId);
}
if(filter.ProductId != null)
{
    query = query.Where(x => x.o.ProductID == filter.ProductId);
}



回答3:


Maybe change it to this:

from O in db.Orders
join C in db.Customers on C.Id equals O.CustID
Where O.ord_date == ( filter.OrderDate ?? o.ord_date) &&
  c.Id == (filter.CustId ?? c.Id) &&
  o.ProductId == (filter.ProductId ?? o.ProductID)
select new {o,c}

Using the ?? operator keeps things a little tidier. It's basically like a coalesce operator for .NET

Other then that, I'm not sure what else you could change.



来源:https://stackoverflow.com/questions/5005920/is-there-a-better-way-of-writing-this-linq-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!