使用 C# 和 SqlKata 查询引擎的多个 where 子句

Posted

技术标签:

【中文标题】使用 C# 和 SqlKata 查询引擎的多个 where 子句【英文标题】:Multiple where clause using C# and SqlKata query engine 【发布时间】:2019-06-18 20:00:10 【问题描述】:

我正在开发一个小型 Web API,它将在后端使用 SqlKata 作为与 SQL Server 对话的查询引擎。在文档中,SqlKata 对多个 where 子句表示以下内容:

多个字段 如果您想针对多个字段过滤查询,请传递一个表示 col/values 的对象。

var query = new Query("Posts").Where(new 
    Year = 2017 ,
    CategoryId = 198 ,
    IsPublished = true,
);

我的意图是使用查询字符串在后端创建 WHERE 子句,但是对于如何将查询字符串的键/值对转换为要在SqlKata 查询。该请求本质上是高度动态的,所以我不能真正使用静态对象。我想知道是否有人对如何构造对象以满足这些要求有任何提示,因为属性(属性名称和/或值)可以是动态的,对象中的属性数量也可以。在我的脑海中,我可以想象在运行时以某种方式将查询字符串的键/值对转换为一个对象,但我被困在如何实现这一点上。

我确实尝试了以下方法,但似乎每次循环迭代都会替换最后一个键/值对,因此您最终只考虑了最近的 WHERE 子句:

                    if (request.QueryStringParameters != null)
                    
                        foreach (var element in request.QueryStringParameters)
                        
                            CreateCloudWatchLog($"query string element.Key value element.Value", context, LogLevel.Trace, environmentLogLevel);

                            if (element.Key != "limit")
                            
                                query = query.Where(element.Key, element.Value);
                            
                            if (element.Key == "limit")
                            
                                query = query.Limit(Convert.ToInt32(element.Value));
                            
                        
                    

我也尝试过这种方法(查询字符串 => json => 动态对象),但我收到错误“参数计数不匹配”(我正在使用一个名为“storenumber”的参数进行测试,其值为 399)

                        var json = JsonConvert.SerializeObject(request.QueryStringParameters, Formatting.Indented);
                        CreateCloudWatchLog($"Serialised query strings = json", context, LogLevel.Trace, environmentLogLevel);
                        var myobject = JsonConvert.DeserializeObject<dynamic>(json);
                        query = query.Where(myobject);

调试日志:

[Trace] Serialised query strings =

    "storenumber": "399"


[Trace] Finished converting JSON to object
[Error] Parameter count mismatch.

【问题讨论】:

你试过.Where(key1, value1).Where(key2, value2)...吗? mjwills - 这实际上是我发布此内容后的下一个想法。我将尝试将查询字符串字典序列化为 json,然后返回动态对象,看看是否可行。 DavidG - 我没有想到这一点,但是如果键/值对的数量是可变的并且在运行时未知,我将如何实现这一点?如果我知道始终只有 - 比方说 - 3 个键/值对,你的建议会很棒。但在这个实现中,可能有一对,也可能有五对,无法判断。 顺便谢谢你们的建议:) 【参考方案1】:

查看文档,您似乎可以使用basic where 方法,该方法接受一个属性和一个值。例如,假设您有一个键值对字典,您可以这样做:

var filters = new Dictionary<string, object>

     "Year", 2017 ,
     "CategoryId", 198 ,
     "IsPublished", true ,


var query = new Query("Posts");

foreach(var filter in filters)

    query = query.Where(filter.Key, filter.Value);

【讨论】:

DavidG 我确实尝试了循环并使用该语法,但它似乎只添加了最后一个键/值对,所以如果它循环通过 3 组键/值对,它似乎替换了最后一个一个在下一次迭代中。 你完全按照我写的那样做吗?请记住,您需要在每次迭代时继续存储query DavidG 我编辑了我的帖子以显示我的版本,但它与您概述的几乎相同。在测试中,似乎只考虑最近传入的键/值对。 那么代码与链接调用相同,它应该可以工作。 那是因为连续的Where 调用是AND 一起调用它们,这意味着where store = 123 AND store = 233 这显然没有意义,这就是为什么只使用最后一个。如果你想使用WHERE IN,那么你应该使用WhereIn("store, new [] 123, 233)。见the docs

以上是关于使用 C# 和 SqlKata 查询引擎的多个 where 子句的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 sqlkata 中查询参数化的表值函数?

基于组件的设计(C# 游戏引擎)

使用 C# 进行查询验证

如何通过oracle在c#中使用多个选择查询

在实体框架 C# 中使用 Lambda 编写多个 Sum() SQL 查询

如何使用多个 XPath 查询在 c# 中选择单个 XML 节点