【问题标题】:SQLKata Dynamic Where ClauseSQLKata 动态 Where 子句
【发布时间】:2019-10-12 00:35:17
【问题描述】:

我正在使用SQLKata 在C# 中构建一个SQL 语句,并在Github 论坛上找到了一些代码,但它无法编译。我需要帮助来编译它。

我在这一行收到两个错误query.Where(q =>

编译错误(第 17 行,第 16 列):并非所有代码路径都在 'System.Func' 类型的 lambda 表达式中返回值

编译错误(第 17 行,第 16 列):无法将 lambda 表达式转换为类型“对象”,因为它不是委托类型

class Group
{
   public List<Condition> Conditions {get; set;}
}

class Condition
{
   public string Field {get; set;}
   public string Operator {get; set;} 
   public object Value {get; set;}  
}

var query = new Query("Countries");

foreach(Group group in groups) 
{
    query.Where(q =>
    {
        foreach(Condition c in group.Conditions)
        {
            q.OrWhere(c.Field, c.Operator, c.Value);
        }
    });
}

.NET Fiddle 是 here

Github 发帖here

更新 我已经根据亚历克斯的回答更新了小提琴。我正在寻找一个子句,所以预期的输出是用括号括起来的 OR 语句。它现在大部分都在按预期工作除了每个组都应该在它自己的括号内,如下所示:

SELECT * FROM [Countries] WHERE ([Group1Field1] = @p0 OR [Group1Field2] > @p1 OR [Group1Field3] = @p5 OR [Group2Field3]

最终更新 弄清楚了。给出上述预期输出。谢谢。

var query = new Query("Countries");

    foreach (Group group in groups)
    {
        query.OrWhere(q => {
        foreach (Condition c in group.Conditions)
        {
            q.OrWhere(c.Field, c.Operator, c.Value);
        }
        return q;

        });

    }
query.Where("Id", "=", 10);

【问题讨论】:

  • 您期望Console.WriteLine(sql); 的输出是什么?
  • 您应该将您的解决方案发布为答案并将其标记为已解决

标签: c# lambda sqlkata


【解决方案1】:

我已更新代码以修复错误。

var query = new Query("Countries");

foreach (Group group in groups)
{
    query.OrWhere(q => {
    foreach (Condition c in group.Conditions)
    {
        q.OrWhere(c.Field, c.Operator, c.Value);
    }
    return q;

    });

}
query.Where("Id", "=", 10);

【讨论】:

    【解决方案2】:

    试试这个:

    List<Group> groups = new List<Group>
    {
        new Group
        {
            Conditions = new List<Condition>
            {
                new Condition {Field = "Group1Field1", Operator = "=", Value="Group1Value1"},
                new Condition {Field = "Group1Field2", Operator = ">", Value="Group1Value2"},
                new Condition {Field = "Group1Field3", Operator = "<", Value="Group1Value3"},
                new Condition {Field = "Group1Field4", Operator = "=", Value="Group1Value4"}
            }
        },
        new Group
        {
            Conditions = new List<Condition>
            {
                new Condition {Field = "Group2Field1", Operator = "=", Value="Group2Value1"},
                new Condition {Field = "Group2Field2", Operator = ">=", Value="Group2Value2"},
                new Condition {Field = "Group2Field3", Operator = "<=", Value="Group2Value3"}
            }
        }
    };
    
    var query = new Query("Countries");
    foreach (Group group in groups)
        foreach (Condition c in group.Conditions)
            query.OrWhere(c.Field, c.Operator, c.Value);
    
    Console.WriteLine(new SqlServerCompiler().Compile(query).Sql);
    

    输出是:

    SELECT * FROM [Countries] WHERE [Group1Field1] = @p0 OR [Group1Field2] > @p1 OR [Group1Field3] < @p2 OR [Group1Field4] = @p3 OR [Group2Field1] = @p4 OR [Group2Field2] >= @p5 OR [Group2Field3] <= @p6
    

    .NET Fiddle

    更新:

    我检查了documentation 和tests 并没有发现比以下更好的东西。 要获得您需要使用的输出:

    foreach (var group in groups)
    {
        if (!group.Conditions.Any())
            continue;
    
        if (group.Conditions.Count == 1)
        {
            var single = group.Conditions.Single();
            query.OrWhereRaw($"([{single.Field}] {single.Operator} ?)", single.Value);
            continue;
        }
    
        var first = group.Conditions.First();
        var last = group.Conditions.Last();
        var others = group.Conditions.Skip(1).Take(group.Conditions.Count - 2);
    
        query.OrWhereRaw($"([{first.Field}] {first.Operator} ?", first.Value);
        foreach (var c in others)
            query.OrWhere(c.Field, c.Operator, c.Value);
        query.OrWhereRaw($"[{last.Field}] {last.Operator} ?)", last.Value);
    }
    
    query.Where("Id", "=", 10);
    

    代替:

    foreach (Group group in groups)
        foreach (Condition c in group.Conditions)
            query.OrWhere(c.Field, c.Operator, c.Value);
    

    .NETFiddle

    【讨论】:

    • 感谢您抽出宝贵时间。这几乎就是我要找的东西。我想创建一个“子句”,所以我希望所有 OR 语句都在括号内。我已经根据您的回答更新了我的 .NET 小提琴,它几乎可以按预期工作。如果需要,请查看并更新。我想要多个子句,每个组一个。所以基本上每个组周围都有括号。
    • @RickS,提供参数值需要什么,即 p0 = Group1Value1, p1=Group1Value2?
    • 我查看了文档,并没有真正看到有关参数化查询的任何内容。壁橱里的东西是这样的:sqlkata.com/…
    猜你喜欢
    • 2019-08-22
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 2013-12-19
    • 2014-03-03
    相关资源
    最近更新 更多