LINQ和多对多关系

5

所以我正在编写一个“动态”Linq查询。我创建了一个“选项”类,用于保存可以成为查询一部分的所有动态选项。其中一些选项属性是List对象,它们保存了SQL Server中许多对多关系的实体ID,我想返回这些实体。下面是一个简短的代码示例和表格描述(为了简洁起见)。

汽车表: Id int PK, Model varchar(50), Year int

颜色表: Id int PK, Name varchar(50)

汽车X颜色表: CarId int PK, ColorId int PK

public IEnumerable<Car> Search(SearchOptions options)
{
    var query = from car in ctx.Cars select car;

    // This works just fine
    if (options.MaxMileage.HasValue) query = query.Where(x => x.Mileage <= options.Mileage.Value);

    // How do I implement this pseudo code. options.Colors is a List<int>
    if (options.Colors.Count > 0)
    {
        query = query.Where(  -- select cars that are in the List<int> of colors --);
    }


    return query;
}

如果你读了代码的注释,就会知道这个问题的答案。 - Scott
谢谢你澄清这么明显的事实(并不) - Phil C
不用谢。总是很乐意帮助那些跟不上步伐的人。 :) - Scott
我总是乐于帮助各种挑战 :) - Phil C
@Scott,我认为@Carnotaurus是正确的——在评论中提出问题很难被注意到。可能应该将问题放在正文中。 - Stephen Chung
3个回答

3

我看到你已经得到了答案,但是也可以考虑以下的替代方案:

var query = 
    from car in ctx.Cars 
    where options.Colors.Count <= 0 || car.CarsXColors.Any(y => options.Colors.Contains(y.Id))
    select car;

这种风格非常常见,因为它生成相同的 SQL 语句,以便数据库引擎或 LINQ 可以缓存查询和/或查询计划,从而实现更快的响应。

如果 options.Colors 为空,数据库查询优化器将自动消除 WHERE 子句,因此您不会在性能上承担任何惩罚。


接受解释,这样我就不必接受自己的答案了。 :) - Scott

2
   query = query.Where(x => options.Colors.Contains(x.ColorID))

ColorId在该实体中不存在。它在查找表中(即多对多关系)。没有单一的ColorId属性。 - Scott

0

解决了自己的问题...

if (options.Colors.Count > 0) 
{
    query = query.Where(x => x.CarsXColors.Any(y => options.Colors.Contains(x.Id)));
}

可能应该是 Contains(y.Id) - Stephen Chung

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接