【问题标题】:Dynamic Where Clause over relational tables with LINQ to SQL使用 LINQ to SQL 的关系表上的动态 Where 子句
【发布时间】:2010-10-16 09:21:07
【问题描述】:

我需要关于 LinqToSql 中关系表(一对多)的动态 where 子句的帮助。

用户从页面中选择条件。 (用户选择子句有 4 个输入)

例如 Customer 表中的 CompanyName 和 CompanyTitle 以及 Order 表中的 OrderDate 和 ShipCity。

用户可以从页面中选择一个或多个界面,代码隐藏处会生成动态查询并选择From LinqToSql。

您可以从其他网页中提供类似类型的示例。

【问题讨论】:

    标签: .net linq linq-to-sql dynamic where-clause


    【解决方案1】:

    您是否正在寻找类似的东西,在其中定义“基本”查询,然后评估参数以确定 where 子句是否合适?

    var result = (from x in context.X
                  select x);
    
    if(some condition)
    {
        result = result.AsQueryable().Where(x => x.companyName == name);
    }
    if(some other condition)
    {
        result = result.AsQueryable().Where(x => x.companyTitle == title);
    }
    
    //return result.ToList();
    //return result.FirstOrDefault();
    //return result.Count(); //etc
    

    我注意到在您的一个 cmets 中您提到您的表没有通过外键连接?我不确定在没有某种参照完整性或关系的情况下如何获得一对多关系?

    【讨论】:

    • 我是 LINQ 新手,但那不是从数据库中检索 所有 数据然后逐步过滤吗?在我看来,对于大量数据,让数据库进行过滤并只返回您想要的数据会更有效。
    • 不,它只在您执行 ToList()、Count() 等操作时执行选择。
    • 澄清一下——数据库将返回所有数据,数据库客户端将过滤行。这与将 WHERE 子句传递给 DB 并将过滤后的数据返回给 DB 客户端不同。上面的代码将执行前者,因此可能会从 DB 向 DB 客户端发送 很多 比严格必要的数据。
    • 不,它没有。我刚刚测试了这个(再次)来验证。实际的 SELECT 命令在您执行需要 .ToList() 之类的结果的操作之前不会执行。如果您不相信我,请附上 SQL Profiler 并亲自查看。
    【解决方案2】:

    dynamic linq library 上查看 ScottGu 的博客。我认为这会有所帮助。

    下面是一个同时命中客户和订单表的查询示例:

     变种查询 =
        db.客户。
        Where("City = @0 and Orders.Count >= @1", "London", 10).
        OrderBy(“公司名称”)。
        Select("new(CompanyName as Name, Phone)");
        

    上面的查询来自C# samples for Visual Studio。下载并查看 \LinqSamples\DynamicQuery 文件夹,您会发现更多示例。

    【讨论】:

    • 我也访问了这个页面。在示例中,他们从一个表中选择并在此表上创建动态 where 子句。
    【解决方案3】:

    取决于您希望它的动态程度 - 正如其他人已经建议的那样,System.Linq.Dynamic 命名空间添加了一些简洁的功能,用于编写在设计时所涉及的实体/成员(表/列)未知的查询。在这种情况下,听起来所涉及的实体和成员是已知的,您只需要在不同的字段之间交替使用 where 子句标准。这是一个例子:

    from cust in dc.Customer
    join ord in dc.Order on cust.CustomerID equals ord.CustomerID
    where (companyName == null || cust.CompanyName == companyName)
      and (companyTitle == null || cust.CompanyTitle == companyTitle)
      and (orderDate == null || ord.OrderDate == orderDate)
      and (shipCity == null || ord.ShipCity == shipCity)
    select new {cust, ord}
    

    【讨论】:

    • 1 个静态 SQL 不好。对于一个查询,只会创建一个查询计划。例如,如果您提供 P1,In 可能会运作良好,但如果您提供 P2 或 P1 和 P3 的组合,则效果不佳。我有一个查询,它连接多个表(5+),可选参数属于不同的表。一个查询计划在 SQL 2005 上不起作用
    • @MichaelFreidgeim 上面的示例将不会导致单个静态 SQL 查询。 L2S 评估客户端可以评估的部分,并生成一个 SQL 查询,其中只包含需要由数据库评估的部分。如果例如companyName 参数为空,公司名称部分将永远不会出现在 SQL where 子句中。这是 Linq-to-SQL 的一大优点。
    【解决方案4】:

    RobS 提供了我认为最有吸引力的解决方案。但是,这是我使用的方法,但后来我意识到它实际上是在完整执行第一个查询(Linq-To-SQL),然后仅使用 LINQ 执行后续的 .Where() 子句。所以这不是一个可行的解决方案,因为整个数据集都会被枚举,然后在内存中被过滤掉。

    如果我错了,请纠正我 - 但这是我注意到的。

    【讨论】:

    • 您可以发布任何示例吗?根据我的经验(通过 SQL Profiler 证明),在您执行某种操作(例如 ToList()、Count() 等)之前不会执行查询。
    猜你喜欢
    • 1970-01-01
    • 2016-06-21
    • 2011-10-03
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    相关资源
    最近更新 更多