【问题标题】:Where comparison from array来自数组的比较
【发布时间】:2018-02-05 01:17:32
【问题描述】:

我有一个结构如下的sql表:

Id-------|-------Attr1--------|-------Attr2------|------Attr3 ------|

1--------|--------真-----|-----假--------|----- -假-----|

2--------|--------真-----|--------真--------|---- ---是的-------|

以此类推,有不同的真/假组合。

我正在尝试构建一个 Linq 查询,该查询可以根据已知的真/假组合提取正确的 Id。

例如,我可以使用以下内容:

public int GetTypeId(string[] arr)
    {
        //arr[0] is true, arr[1] is false
        return _context.Types
            .FirstOrDefault(x => x.Attr1 == arr[0] && x.Attr2 ==arr[1]).Id;
    }

这将产生一个 1 的 ID。

现在我的问题是如何正确地使它成为一个动态函数,其中有 10 个属性列,我可以输入一个包含任意数量元素的数组来进行 where 比较(比如第一次是 Attr1 和 Attr2,然后是 Attr3下一个是 Attr4 和 Attr5)。

有没有一种有效的方法来做到这一点?我最大的问题是 .FirstOrDefault() 函数不接受串联字符串。

【问题讨论】:

  • 您可能需要在这里使用反射,例如stackoverflow.com/questions/737151/…,然后将其与数组值进行比较。但是,我宁愿重构受影响类中的比较代码,我认为这是更健壮和可维护的方式。
  • 您还需要在中间进行一步将字符串解析为布尔值,否则您无法将字符串“真”和“假”与布尔值进行比较。

标签: c# sql entity-framework linq


【解决方案1】:

你应该动态创建Expressionpredicate

public int GetTypeId(string[] arr, int start = 1)
{
    var arg = Expression.Parameter(typeof(TypeClass), "x");            
    Expression andExpr = null;
    for(var i = 0; i < arr.Length; i++)
    {
        var exprProp = Expression.Property(arg, "Attr" + (i + start));
        var exprVal = Expression.Constant(arr[i]);
        var exprEq = Expression.Equal(exprProp, exprVal);
        andExpr = andExpr == null ? exprEq : Expression.AndAlso(andExpr, exprEq);
    }                        
    var predicate = Expression.Lambda<Func<TypeClass, bool>>(andExpr, arg);

    return _context.Types.FirstOrDefault(predicate).Id;
}

如果你不想从Attr1(默认行为)开始比较,而是从Attr3你 应该将 3 作为 start 参数传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2020-06-15
    • 1970-01-01
    • 2023-02-03
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    相关资源
    最近更新 更多