【问题标题】:Where clause with a list of field combinations带有字段组合列表的 Where 子句
【发布时间】:2013-06-11 23:24:17
【问题描述】:

我有一个要搜索的字段组合列表。该列表实际上可以包含多达 100 个项目,我正在查询的表此时有超过 100 万条记录。

一个例子:

create table mytable
(
    foo int not null
    ,bar int not null
    ,baz int not null
)

insert into
    mytable
values
    (1, 1, 11)
    ,(1, 2, 12)
    ,(1, 3, 13)
    ,(2, 1, 21)
    ,(2, 2, 22)
    ,(2, 3, 23)
    ,(3, 1, 31)
    ,(3, 2, 32)
    ,(3, 3, 33)

一种可能的数据检索方式:

select
    foo
    ,bar
    ,baz
from
    mytable
where
    (foo = 1 and bar = 3)
    or (foo = 2 and bar = 1)
    or (foo = 3 and bar = 2)

另一种可能的方式:

declare @filtercombos table
(
    foo int not null
    ,bar int not null
)

insert into
    @filtercombos
values
    (1, 3)
    ,(2, 1)
    ,(3, 2)

select
    mytable.foo
    ,mytable.bar
    ,mytable.baz
from
    @filtercombos fc
    left join mytable on mytable.foo = fc.foo and mytable.bar = fc.bar

两者都会返回这个数据:

foo         bar         baz
----------- ----------- -----------
1           3           13
2           1           21
3           2           32

现在,如果这是单个值的列表,我可以使用.Where(item => myList.Contains(item.foo))。如何进行上述查询?我唯一能想到的就是在 DbContext 上执行 SQL,但如果可能的话,我想避免这种情况。

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    LINQKit 的 PredicateBuilder 正是您所需要的!

    var query = from u in context.Users select u;
    var pred = Predicate.False<User>();
    
    foreach(var filter in combofilers)
        pred = pred.Or(u => u.Username == filter.Foo && u.Language == filter.Bar);
    
    return query.Where(pred.Expand()).FirstOrDefault();
    // or return query.AsExpandable().Where(pred).FirstOrDefault();
    

    Dynamic where clause (OR) in Linq to Entities

    【讨论】:

    • 这行得通,Profiler 显示查询扩展为where (foo = 1 and bar = 3) or (foo = 2 and bar = 1) or (foo = 3 and bar = 2)
    【解决方案2】:

    如果您已经在另一个列表中拥有组合列表,您可以这样做。

    var query = from m in Context.mytables
        select m;
    
    foreach (var foobar in foobars)
    {
        query = query.Where(x => x.foo == foobar.foo && x.bar == foobar.bar);
    }
    
    return query.ToList();
    

    【讨论】:

    【解决方案3】:

    或者类似于这个问题的答案可能会有所帮助。

    Entity Framework - Join to a List

    【讨论】:

    • 该问题的第一个解决方案是存储过程(类似于在 DbContext 上执行 SQL),第二个解决方案,如解释的那样,将所有记录拉到内存中,我无法通过百万条记录。
    猜你喜欢
    • 2023-01-31
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多