'Suggestions for designing complex LINQ code
What are your suggestions for designing linq code in project? 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.
Solution 1:[1]
you can write extensions for your objects;
Main code;
IQuerable itemList = _coreRepository.GetSomeItems()
.WithStates(OperationIdentity.SendToSomeWhere)
.BetweenDates(StartDate, EndDate);
Extension;
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;
}
Solution 2:[2]
I like to put aside big Select statements that are used many times using extension methods.
public static IQueryable<SomeEntityPM> SelectEntityPM(this IQueryable<SomeEntity> entities)
{
return entities.Select(a => new SomeEntityPM { ... });
}
Usage:
ObjectCtx.SomeEntities.SelectEntityPM();
Solution 3:[3]
One useful pattern for this is creating a reusable predicate library. Check out this page on the LINQ PredicateBuilder for more info.
Solution 4:[4]
A vew things I often do:
1) Layout: always start a query at the next line. Example: Don't do this
var allCustomersThatDontContainUnpayedOrders = from customer in db.Customers
where customer.Orders ...
select customer;
But do this:
var allCustomersThatDontContainUnpayedOrders =
from customer in db.Customers
where customer.Orders ...
select customer;
2) Use multiple where
clauses where you can. I try to find the second snippet more readable than the first:
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) Prevent joins if you can. LINQ to SQL often allows you to just 'dot' over all parent-child relations without using hard-to-understand join
statements.
4) Often you will see that many queries look alike. You might always want to filter certain records based on rights of a user. You can extract this code in a method:
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;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | NetSide |
Solution 2 | Stephane |
Solution 3 | Chris Fulstow |
Solution 4 | Steven |