Modular (refactoring) Linq queries

I have several Linq queries. Semantically, they

  • connection b connect c connect d, where filter1 (a) && & filter2 (c) && filter3 (d)

  • connection b connects c, where filter1 (a) && & filter2 (c)

  • connection b connect c connect e, where filter1 (a) && & filter2 (c) && filter4 (e)

...

I want to be able to share the common part:

a join b join c where filter1(a) && filter2(c) 

and dynamically add join d and filter3(d)

Is there any way to do this? I already use Predicate Builder to dynamically create conditional expressions (filters).

EDIT: I am using Linq-to-SQL.

EDIT: The base query looks like this:

 from a in As.AsExpandable() join b in Bs on a.Id equals b.PId join c in Cs on b.Id equals c.PId where filter1(a) && filter2(b) && filter3(c) select new A { ... } 
Filters

are predicates in the Predicate Builder. The query type is IQueryable<A> .

Next, I would like to join this with d

 from a in BaseQuery() join d in D on a.Id equals d.PId 

join d .. is currently causing a compilation error:

The type of one of the expressions in the join clause is invalid. Type input error in Join call

+4
source share
2 answers

Your example is a bit vague, but it's easy to create a method that returns an IQueryable<T> and reuse this method if that is what you mean. Here is an example:

 // Reusable method public IQueryable<SomeObject> GetSomeObjectsByFilter(Context c) { return from someObject in context.SomeObjects where cBAAmount < 1000 where c.Roles.Contains(r => r.Name == "Admin") select someObject; } 

You can reuse this method in other places, for example:

 var q = from c in GetSomeObjectsByFilter(context) where !cDContains(d => d.Items.Any(i => i.Value > 100)) select c; 

Since the IQueryable method works, only the final query (the collection that you start iterating) will call the database, which will allow you to create a system with a high degree of support, reusing business logic that runs efficiently inside the database, to lose any performance.

I do this all the time and it improves the maintainability of my code. It works no matter what O / RM tool you run, because there is no difference in the composition of the Queryable<T> between writing a query in one world or splitting it into different methods.

Note that sometimes you need some smart transformations to get duplicate parts in one method. Things that can help return grouped sets and return a set of a different type than what you think is needed. This sounds a bit eloquent, but just ask the question here when you have problems with splitting the method. There are enough people here who can help you.

+3
source

I can easily answer your question. Linq makes it easy to add wherewhere clauses to an existing query.

Example:

 var x = db.Table1.where(w => w.field1 == nTestValue); x = x.where(w => w.field2 == nTestValue2); 

I believe that you can unite too, but I need to find an example in some old code. I'll see if anyone else starts with him soon.

+1
source

All Articles