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开发者_如何学JAVA 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.
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;
}
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();
One useful pattern for this is creating a reusable predicate library. Check out this page on the LINQ PredicateBuilder for more info.
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;
}
精彩评论