简体   繁体   中英

Dynamic Linq “Where statement” with Relation

I'm trying to build a query using Dynamic Linq and a where string statement calculated by myself. For example:

List<Publication> results = new List<Publication>();

// Just an example, previously calculated dynamically
string filterQuery = "(Id = 1 and Number = 2)";

IQueryable<Publication> query = db.Publications.Include(i => i.Product);
query = query.Where(filterQuery);

results = query.OrderBy(orderQuery).ToList();

This is working great and I get a List of Publications with Products. Now... the question is. How can I make a string statement to get results based on a relation to Product using Dynamic Linq and a string statement?

Something like:

string filterQuery = "(Id = 1 and Number = 2 and Products.Id = 1)"

I am not sure why you're doing this, but the following should work:

List<Publication> results = new List<Publication>();

// Just an example, previously calculated dynamically
string filterQuery1 = "(Id = 1)"
string filterQuery2 = "(Id = 1 and Number = 2)";

IQueryable<Publication> query = db.Publications.
Where(filterQuery1).     
Include(i => i.Product);
query = query.Where(filterQuery2);

results = query.OrderBy(orderQuery).ToList();

After a lot of research and trying things, this is an easy and friendly way using the same Dynamic Linq library:

List<Publication> results = new List<Publication>();

// Just an example, previously calculated dynamically
string filterQuery = "(Id = 1 and Number = 2)";
string filterQueryChildren = "Products.Any(Id == 1)"

IQueryable<Publication> query = db.Publications.Include(i => i.Product).Where(filterQueryChildren);

query = query.Where(filterQuery);

results = query.OrderBy(orderQuery).ToList();

To make dynamic LINQ query, you need a library that support it or doing it yourself with Expression Tree

See: Entity Framework Dynamic Query Library

Disclaimer : I'm the owner of the project Eval-Expression.NET

This library allows you to evaluate, compile, and execute code at runtime.

The library also contains extension method for dynamic LINQ

Wiki: Eval Dynamic LINQ

Example

// using Z.Expressions; // Don't forget to include this.

// The filterQuery must use the C# syntax
string filterQuery = "x.Id == 1 && x.Number = 2";

IQueryable<Publication> query = db.Publications.Include(i => i.Product);
query = query.Where(x => filterQuery);

EDIT: Answer sub question

Great but how can I filter by Product?

Entity Framework doesn't support filter in Include method.

However, EF+ do

Disclaimer : I'm the owner of Entity Framework Plus

See: EF+ Query IncludeFilter

By combining both libraries, you can achieve your desired result:

// Extension method must be registered, otherwise the library cannot be aware of which extension method exists!
EvalManager.DefaultContext.RegisterExtensionMethod(typeof (QueryIncludeFilterExtensions));

string where1 = "x.Id == 1 && x.Number == 2";
string where2 = "y.Id == 3";

var left2 = ctx.Publications
    .Where(x => where1)
    .Execute<IQueryable<Publication>>("IncludeFilter(x => x.Product.Where(y => " + where2 + "))")
    .ToList();

If you want to try this solution, make sure you download the latest version of Eval-Expression.NET. We just have fixed few min ago an issue we found by trying your scenario.

EDIT2: Answer sub question

Here is what I recommend you.

Try the query without our library then try it dynamically after.

That's easier to find the compilation error or what you want to do really.

By example, we probably didn't understand the initial problem correctly and suggested IncludeFilter which you don't want. I assumed you wanted to filter multiple products. However, it looks you only have one product per publication, so the Where clause method obviously doesn't exist.

Maybe this is more what you are looking for:

string where1 = "x.Id == 1 && x.Number == 2 && x.Product.Id == 3";

var left2 = ctx.Publications
    .Include(x => x.Product)
    .Where(where1)
    .ToList();

So in short, try the query by hardcoding it (without dynamic) then you will know how to use it dynamically after.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM