【问题标题】:How to construct a Where clause for an EntitySet如何为 EntitySet 构造 Where 子句
【发布时间】:2014-05-16 03:07:50
【问题描述】:

假设我有两个用外键约束连接的表。考虑以下代码:

using(var dc = TestDataContext())
{
    IQueryable<ParentTable> query = dc.ParentTable;  
    query = query.Where(t => t.ChildTable.Where(c => c.Name.StartsWith("#")).Any());
    Console.WriteLine(query.Count());
}

如果我需要在某些条件下扩展 Where 子句,我会简单地链接 Where 子句:

if(...)
    query = query.Where(...);
...

其实它会通过sql中的AND语句添加到原来的Where子句中。

现在想象一下,我需要在ChildTable 上动态构造Where 子句ParentTable Where 子句...

我尝试过这样做:

using(var dc = TestDataContext())
{
    IQueryable<ParentTable> query = dc.ParentTable;  

    //here specify the necessary condition 
    Func<ChildTable, bool> where;
    if(...)
        where = c => c.Name.StartsWith("#");
    else ...

    query = query.Where(t => t.ChildTable.Any(where));
    Console.WriteLine(query.Count());
}

但是它抛出了NotSupportedException,说它无法正确地将whereFunc 指定为Any 转换为sql。

我以为我可以指定Expression&lt;Func&lt;ChildTable, bool&gt;&gt;,但t.ChildTableEntitySet&lt;ChildTable&gt;,所以它没有实现IQueryable&lt;T&gt;...所以自定义Func&lt;&gt; 无法正确翻译成sql。

除了每次简单地重写整个语句之外,有没有办法实现这个目标:

1. query = query.Where(t => t.ChildTable.Where(c => c.Name.StartsWith("#")).Any());

2. query = query.Where(t => t.ChildTable.Where(c => c.Name.StartsWith("#") && ...).Any()));

...

【问题讨论】:

    标签: c# linq linq-to-sql


    【解决方案1】:

    在需要动态 where 子句的情况下,我喜欢使用 PredicateBuilder

    将该网站上的示例翻译成您的问题会得到以下代码。如果您使用的是 EF,您可能需要使用 .AsExpandable() 进行讨论,请参阅链接了解更多信息。

    var predicate = PredicateBuilder.False<ParentTable>();
    predicate = predicate.Or(p => p.ChildTable.Any(c => c.Name.StartsWith("#"));
    
    var keywords = "search terms go here";
    foreach (var keyword in keywords)
    {
      var temp = keyword;
      predicate = predicate.Or(p => p.ChildTable.Any(c => c.Name.Contains(temp));
    }
    
    using(var dc = TestDataContext())
    {
      Console.WriteLine(dc.ParentTable.Where(predicate).Count());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      • 2015-06-22
      • 2011-08-14
      • 1970-01-01
      • 2012-10-02
      • 2019-08-25
      相关资源
      最近更新 更多