【问题标题】:C# Dynamic WHERE clause in a LINQ to SQL QueryLINQ to SQL 查询中的 C# 动态 WHERE 子句
【发布时间】:2009-08-20 13:18:07
【问题描述】:

我想执行一个带有动态 where 子句的 LINQ 查询,具体取决于用户为其条件输入了多少不同的选项。

这可能吗?

我在下面发布了我希望它如何工作的代码。

有人有什么建议吗?

附:我尝试使用 .Contains 方法(在 SQL 上生成 WHERE IN,但是参数数量高于 2100 阈值并导致错误“LINQ 传入的表格数据流 (TDS) 远程过程调用 (RPC) 协议流不正确. 此 RPC 请求中提供的参数过多。最大值为 2100"。

private struct ProductStruct
{
    public long ProductID;
}

private struct FilterStruct
{
    public long ProductTypeFieldID;
    public long ValueNumber;
}

List<FilterStruct> filterList = new List<FilterStruct>();
filterList.Add(new FilterStruct { ProductTypeFieldID = 3, ValueNumber = 195 });
filterList.Add(new FilterStruct { ProductTypeFieldID = 8, ValueNumber = 55 });
 
List<ProductStruct> productList = new List<ProductStruct>();
 
productList = (from pfv in dC.ProductFieldValues
                           where
                                foreach (FilterStruct filter in filterList)
                                {
                                    pfv.ProductTypeFieldID == filter.ProductTypeFieldID
                                    && pfv.ValueNumber == filter.ValueNumber
                                }
                           select new ProductStruct
                           {
                               ProductID = pfv.ProductID
                           }).ToList();

编辑

这看起来好像很方便,但不适用于动态 where in?

private void Option2()
{
    try
    {
        LinqDataDataContext dataConnection = new LinqDataDataContext(ConnectionString);

        List<FilterStruct> filterList = new List<FilterStruct>();
            filterList.Add(new FilterStruct { ProductTypeFieldID = 3, ValueNumber = 195 });
            filterList.Add(new FilterStruct { ProductTypeFieldID = 8, ValueNumber = 55 });

        string whereClause = null;
        foreach (FilterStruct filter in filterList)
        {
            if (whereClause != null)
                whereClause += "AND ";

            whereClause += string.Format("ProductID IN (SELECT ProductID FROM ProductFieldValue WHERE ProductTypeFieldID = {0} AND ValueNumber = {1})", filter.ProductTypeFieldID, filter.ValueNumber);
        }

        List<ProductStruct> productList = new List<ProductStruct>();
            productList = (from pfv in dataConnection.ProductFieldValues.Where(whereClause)
                            select new ProductStruct
                                  {
                                  ProductID = pfv.ProductID
                                  }).ToList();
    } 
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

【问题讨论】:

    标签: .net sql-server-2005 linq-to-sql c#-3.0


    【解决方案1】:

    从这里接受的答案:How do I build up LINQ dynamically

    这适用于 .AsQueryable() 类,但如果您使用“as iQueryable()”,则可以使用 .Enumerable() 类

    【讨论】:

    • 我认为使用动态 LINQ 并将 where 子句构建为字符串的想法是值得的。
    • 您可能想在此处发布摘要,以便您的答案独立。
    【解决方案2】:

    您可以使用 JOIN 子句:

    from pfv in dC.ProductFieldValues
    join filter in filterList on (
        pfv.ProductTypeFieldID == filter.ProductTypeFieldID 
        && pfv.ValueNumber == filter.ValueNumber
    )
    select new ProductStruct                           
    {                               
        ProductID = pfv.ProductID                           
    }
    

    【讨论】:

    • 我认为这只有在实现原始请求并且您使用 LINQ to Objects 进行连接时才有效。我假设 OP 希望在 SQL 服务器上完成过滤,否则他可以遍历它们并删除他不想要的那些。
    【解决方案3】:

    这是一个在 VB 中使用 IQueryable 的简单示例。

    Private Function GetZeroScoreWhere(ByVal qry As IQueryable(Of ScoreTest), ByVal score As ScoreTest) As IQueryable(Of ScoreTest)
        If score.CallType = ScoreTest.CallTypeEnum.XXX Then
            Return qry.Where(Function(c) c.AvgScore.Value = 0 Or c.Zero.Trim <> String.Empty)
        End If
    
        Return qry.Where(Function(c) c.ValidScore.Value = 0)
    End Function
    

    C#中相同的代码:

    private IQueryable<ScoreTest> GetZeroScoreWhere(IQueryable<ScoreTest> qry, ScoreTest score)
    {
        if(score.CallType == ScoreTest.CallTypeEnum.XXX)
        {
            Return qry.Where(c => c.AvgScore.Value == 0 || c.Zero.Trim != String.Empty)
        }
    
        Return qry.Where(c => c.ValidScore.Value == 0)    
    }
    

    【讨论】:

      【解决方案4】:

      我在类似问题中得到的答案对我有用:

      How do you add dynamic 'where' clauses to a linq query?

      (答案是使用Predicate Builder

      【讨论】:

        猜你喜欢
        • 2016-06-21
        • 1970-01-01
        • 2011-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-03
        • 1970-01-01
        • 2012-02-25
        相关资源
        最近更新 更多