我正在将实现相当标准搜索功能的存储过程转换为Entity Framework代码,并且我不太确定如何完成这些SQL正在做的事情:
SELECT
*
FROM
MyTable a
WHERE
@parameter1 = 0 OR a.Id IN
(
SELECT ot.Id FROM OtherTable ot
WHERE ot.Id = @parameter1
AND (@parameter2 = 0 OR ot.OtherValue = @parameter2)
)
基本上,传入了一些可选的搜索参数,如果它们不为零,它们将用作过滤器。很标准。
在上面的案例中,有一个M:1的关系,其中OtherTable在“很多”方面。
我看到两个选项,但我似乎无法获得正确的语法:
(1)我可以使用条件Where来模拟SP中正在进行的操作 条款(Example Here)。我试过这样的事情:
.WhereIf(search.Id != 0, mytable => search.AttributeId == mytable.OtherTables)
对于@ parameter2,必须进一步过滤。但无论如何,mytable.OtherTables是一个集合,因为它在“很多”方面,所以我不能使用(例如)mytable.OtherTables.Id。
(2)我可以将它转换为连接,但是连接必须是有条件的(如果@ parameter1!= 0,则仅包括连接)。我不确定L2S / EF是否可以有条件地加入。
答案 0 :(得分:2)
如何有条件地添加Where
并仅将相关位发送到SQL,而不是将所有内容发送到SQL并尝试编写复杂的查询。
请记住,Linq使用延迟执行,这允许我们逐个构建我们的查询,然后在我们准备好时执行它。
IQueryable<MyTable> myTableQuery = context.MyTables.AsQueryable();
if (parameter1 != 0)
{
IQueryable<OtherTable> otherTableQuery = context.OtherTables.AsQueryable();
if (parameter2 != 0)
{
otherTableQuery = otherTableQuery.Where(ot => OtherValue = parameter2);
}
myTableQuery = myTableQuery.Where(mt => otherTableQuery.Any(ot => ot.Id = mt.Id));
}
return myTableQuery.ToList();
请原谅任何拼写错误,这是在浏览器中编写的。