2

我正在将实现非常标准的搜索功能的存储过程转换为实体框架代码,并且不太确定如何完成这段 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 中正在执行的操作。我试过这样的事情:

.WhereIf(search.Id != 0, mytable => search.AttributeId == mytable.OtherTables)

这必须为@parameter2 进一步过滤。但无论如何,mytable.OtherTables 是一个集合,因为它在“多”端,所以我不能使用(例如)mytable.OtherTables.Id。

(2) 我可以将其转换为联接,但联接必须是有条件的(仅在 @parameter1 != 0 时才包括联接)。我不确定 L2S/EF 是否可以有条件地加入。

4

1 回答 1

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();

请原谅任何错别字,这是在浏览器中编写的。

于 2013-07-12T19:09:31.253 回答