简体   繁体   中英

LINQ to Entities, Where Any In

How to write 'Where Any In' in LINQ to Entity?

Here is my model :

class Chair
{
    public int Id { get; set; }
    public int TableId { get; set; }
    public Table Table { get; set; }

}

class Table
{
    public int Id { get; set; }

    public ICollection<Chair> Chairs { get; set; }
    public ICollection<Category> Categories { get; set; }
    public Table()
    {
        Chairs = new List<Chair>();
        Categories = new List<Category>();
    }
}

class Category
{
    public int Id { get; set; }
    public ICollection<Table> Tables { get; set; }
}

I also got a simple list of Category :

List<Category> myCategories = new List<Category>(c,d,e);

I want to get only that Chairs that belongs to Table that got one of the Category from myCategories List. Thats what im trying to do :

var result = 
ctx.Chairs.Where(x => x.Table.Categories.Any(y => myCategories.Any(z => z.Id == y.Id))).ToList();

I think its ok but what i get is error :

"Unable to create a constant value of type 'ConsoleApplication1.Category'. Only primitive types or enumeration types are supported in this context"

this is because ctx.Chairs is a collection that is in database, you should retrieve that collection first in order to compare it with in-memory data:

var result = ctx
    .Chairs
    .AsEnumerable() // retrieve data
    .Where(x => 
        x.Table.Categories.Any(y => 
            myCategories.Any(z => z.Id == y.Id)))
    .ToList();

EDIT: that wouldn't be the correct thing to do if you have a lot of entities on database, what you can do is to split it into two queries:

var tables = ctx.Tables
   .Where(x => 
        x.Categories.Any(y => 
            myCategories.Any(z => z.Id == y.Id)));

var result = ctx.Chairs
    .Where(x => 
        tables.Any(t=> t.Id == x.TableId))
    .ToList();

You can select Ids from myCategories and use it last statement.

var CategoryIds = myCategories.Select(ct => ct.Id);
var result = ctx.Chairs.Where(x => x.Table.Categories.Any(y => CategoryIds.Any(z => z == y.Id))).ToList();

Try to compare with in-memory categories Ids collection, instead of categories collection.

var myCategoriesIds = myCategories.Select(c => c.Id).ToArray();

var result =
    context.Chairs
        .Where(
            x => x.Table.Categories.Any(
                y => myCategoriesIds.Contains(y.Id)))
        .ToList();

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