c# - 如何使用 Dapper 扩展谓词实现 "IN"子句?

标签 c# dapper dapper-extensions

我想使用 Dapper Extensions Predicate 替换此查询?

SELECT * 
FROM SomeTable 
WHERE id IN (commaSeparatedListOfIDs)

commaSeparatedListOfIDsIntegerIEnumerable

到目前为止我已经尝试过:

using (SqlConnection cn = new SqlConnection(_connectionString))
{
    cn.Open();
    var predicate = Predicates.Field<SomeTable>(f => f.Id, Operator.???, commaSeparatedListOfIDs);
    IEnumerable<SomeTable> list = cn.GetList<SomeTable>(predicate);
    cn.Close();
}

我需要一个运算符Operator.In,但它在 Dapper Extensions 中不存在。

我应该如何使用 Dapper Extensions Predicate 系统实现“IN”子句?

最佳答案

解决方案 1:

PredicateGroupGroupOperator.Or 结合使用是一种解决方案。

var predicateGroup = new PredicateGroup { Operator = GroupOperator.Or, Predicates = new List<IPredicate>() };
foreach(int thisID in commaSeparatedListOfIDs)
{
    var predicate = Predicates.Field<SomeTable>(f => f.Id, Operator.Eq, thisID);
    predicateGroup.Predicates.Add(predicate);
}
IEnumerable<SomeTable> list = cn.GetList<SomeTable>(predicateGroup);

请引用thisthis链接。

解决方案 2:

正如您在回答中提到的和 this链接,将 FieldPredicate (Predicates.Field) 与 Operator.Eq 一起使用,并传递 IEnumerable 参数应该执行相同的操作。

var predicate = Predicates.Field<SomeTable>(f => f.Id, Operator.Eq, commaSeparatedListOfIDs);

此处 Eq 应根据 this 在内部翻译为 IN 子句GitHub 上 Dapper Extensions 的源代码。

if(Value is IEnumerable && !(Value is string))
{
    if(Operator != Operator.Eq)
    {
        throw new ArgumentException("Operator must be set to Eq for Enumerable types");
    }

    List<string> @params = new List<string>();
    foreach(var value in (IEnumerable)Value)
    {
        string valueParameterName = parameters.SetParameterName(this.PropertyName, value, sqlGenerator.Configuration.Dialect.ParameterPrefix);
        @params.Add(valueParameterName);
    }

    string paramStrings = @params.Aggregate(new StringBuilder(), (sb, s) => sb.Append((sb.Length != 0 ? ", " : string.Empty) + s), sb => sb.ToString());
    return string.Format("({0} {1}IN ({2}))", columnName, Not ? "NOT " : string.Empty, paramStrings);
}

要将上面提到的 IN 子句转换为 NOT IN 子句,请使用最后一个 bool not 参数。请引用this回答以获取更多详细信息。
示例代码如下:

var predicate = Predicates.Field<Customer>(f => f.CustomerID, Operator.Eq, commaSeparatedListOfIDs, true);

关于c# - 如何使用 Dapper 扩展谓词实现 "IN"子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49777139/

相关文章:

c# - 如何选择多个文件夹

c# - http.post 在 Angular 5 中不起作用

c# - Dapper 抛出 "Invalid type owner for DynamicMethod."

Dapper 扩展更改架构

c# - 种子方法如何使用foreach循环?

c# 将窗体固定到桌面

c# - ASP.NET Core 在 ExternalLoginSignInAsync 之后获取 UserId

c# - 使用来自两个不同表的两个 SELECT 语句

mysql - DapperExtensions 谓词中不区分大小写的比较

c# - 您如何注册 DapperExtension ClassMapper 子类以便使用它们?