Что вы предлагаете для разработки кода linq в проекте? Especially, I`m interesting in code design of big and complex linq queries?
For example, you know, that you need to write a lot of huge linq stuff, maybe some of your code will have duplicate parts, maybe not, and you need:
Make the code easily supportive - means, if you need to change something . - you are changing one thing, not many
Make the code easy to read - means, if you need to find something - you easily doing this.
You can use your examples, maybe your practice. Maybe some patterns, that you saw anywhere - anything.
Saying linq I mean any linq, linq to sql, linq to objects, linq to xml, etc.
Tnx
вы можете писать расширения для своих объектов;
Основной код;
IQuerable itemList = _coreRepository.GetSomeItems()
.WithStates(OperationIdentity.SendToSomeWhere)
.BetweenDates(StartDate, EndDate);
Расширение;
public static IQueryable<SomeObject> BetweenDates(this IQueryable<SomeObject> query, DateTime startDate, DateTime endDate)
{
return from p in query
where p.CompletedDate >= startDate && p.CompletedDate < endDate
select p;
}
Мне нравится отбрасывать большие операторы Select, которые используются много раз, используя методы расширения.
public static IQueryable<SomeEntityPM> SelectEntityPM(this IQueryable<SomeEntity> entities)
{
return entities.Select(a => new SomeEntityPM { ... });
}
Использование:
ObjectCtx.SomeEntities.SelectEntityPM();
Одним из полезных шаблонов для этого является создание многократно используемой библиотеки предикатов. Посмотрите эту страницу о LINQ PredicateBuilder для получения дополнительной информации.
A vew things I often do:
1) Макет: всегда начинайте запрос со следующей строки. Пример: Не делайте так
var allCustomersThatDontContainUnpayedOrders = from customer in db.Customers
where customer.Orders ...
select customer;
Но делайте так:
var allCustomersThatDontContainUnpayedOrders =
from customer in db.Customers
where customer.Orders ...
select customer;
2) Используйте несколько где
клаузул, где это возможно. Я стараюсь, чтобы второй фрагмент был более читабельным, чем первый:
var results =
from customer in db.Customers
where customer.Name.Contains(search) && customer.Address.City != null &&
customer.Employee.IsSenior
select customer;
var results =
from customer in db.Customers
where customer.Name.Contains(search)
where customer.Address.City != null
where customer.Employee.IsSenior
select customer;
3) Предотвращайте соединения, если можете. LINQ to SQL часто позволяет просто "поставить точку" над всеми отношениями родитель-ребенок без использования труднопонимаемых операторов join
.
4) Часто вы увидите, что многие запросы выглядят одинаково. Вы всегда можете захотеть отфильтровать определенные записи на основе прав пользователя. Вы можете извлечь этот код в метод:
var customers = db.Customers;
customers = FilterBasedOnUserRights(customers, currentUser);
public static IQueryable<Customer> FilterBasedOnUserRights(
IQueryable<Customers customers, User currentUser)
{
return
from customer in customers
where [big complicated where clause]
select customer;
}