2

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

SELECT * 
FROM SomeTable 
WHERE id IN (commaSeparatedListOfIDs)

commaSeparatedListOfIDs是一个IEnumerable。_Integer

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

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 Operator.In,但它在 Dapper Extensions 中不存在。

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

4

2 回答 2

4

解决方案1:

使用PredicateGroupwithGroupOperator.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);

请参考这个这个链接。

解决方案2:

正如您在回答和链接中提到的那样,使用 FieldPredicate ( Predicates.Field)Operator.Eq和传递IEnumerable参数应该做同样的事情。

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

这里Eq应该按照GitHub 上 Dapper Extensions 的源代码在内部翻译成IN子句。

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参数。有关详细信息,请参阅此答案。
示例代码如下:

var predicate = Predicates.Field<Customer>(f => f.CustomerID, Operator.Eq, commaSeparatedListOfIDs, true);
于 2018-04-11T15:18:05.363 回答
0

基于此链接Github Issue

如果您使用 FieldPredicate,请设置为 Equal 并传入一个数组,它将转换为 IN。

所以,正确的方法是这样。

using (SqlConnection cn = new SqlConnection(_connectionString))
{
    cn.Open();
    var predicate = Predicates.Field<SomeTable>(f => f.Id, Operator.In, commaSeparatedListOfIDs);
    IEnumerable<SomeTable> list = cn.GetList<SomeTable>(predicate);
    cn.Close();
}
于 2018-04-11T14:27:16.483 回答