Есть ли лучший способ написания этого Linq Query - PullRequest
2 голосов
/ 15 февраля 2011

Пример

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 }

Когда я запускаю профиль, он имеет много регистров, как я и ожидал.но у меня гораздо больше контроля над условием, что я вставил в C #, как я могу использовать свой контроль над условием где и помещать условие где только когда фильтр доступен для него

Это улучшит мое качество SQLкоторый идет в БД.

С наилучшими пожеланиями Vinay.

Ответы [ 3 ]

2 голосов
/ 15 февраля 2011

Учитывая, что условия не зависят от запроса, вы могли бы вывести условия из запроса и построить его постепенно:

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);
}
2 голосов
/ 15 февраля 2011

Общее решение для такого рода проблем заключается в использовании PredicateBuilder для динамического создания соответствующего предиката.

Сначала создайте предикат:

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);

...

Итогда ваш запрос становится:

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};      
0 голосов
/ 15 февраля 2011

Может быть, изменить это на:

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}

Использование ?? оператор делает вещи немного аккуратнее. Это в основном как оператор объединения для .NET

Кроме этого, я не уверен, что еще ты мог бы изменить.

...