动态Where条件

本文关键字:条件 Where 动态 | 更新日期: 2023-09-27 18:27:52

我遇到了一个小问题:)我有一个列表,其中一些参数是重复的。我必须把它去掉。我不能使用Distinct,因为我只能看到一些字段(而不是全部)。我认为使用lambda epxressions是一个很好的选择。

我有一个关于我工作对象的声明,不一样,但想法相似。

var keys = new string[] {"column1", "column2"};
var repeatedValues = new object[] {5, 15};
var values = new List<Dictionary<string, object>>();
//MAKE FAKE DOUBLE
values.Add(new Dictionary<string, object> { 
            { "column1", 5 }, { "column2", 15 }, { "column3", "test" }, 
            { "column4", "test1" } });
for (int i = 0; i < 10; i++)
{
   values.Add(new Dictionary<string, object> {
               {"column1", i}, {"column2", 10 + i},  "column3", "test"}, 
               {"column4", "test1"}});
}

keys列的长度始终与repeatedValues相同,但发生了更改,有些长度为1,另一些为2,3,5。不超过5

这些键类似于数据库表上的primaryKeys。这很相似。所以我们在"主键列"中寻找重复项——我认为这是一个很好的比较。

我们在该示例中看到,重复is在"column1"中的值为5,在"column2"中为15。我之前怎么说我必须删除,但之前我必须计算重复的项目。

我试着做这样的代码(我知道函数方法awalys失败becouse(object)1==(object)1总是返回false,但它是一个例子:

Expression expression = null;
for (int i = 0; i < keys.Length; i++)
{
    Expression<Func<Dictionary<string, object>, bool>> exp = x => x[keys[i]] == repeatedValues[i];
    if (expression == null)
      expression = exp.Body;
    else
      expression = Expression.AndAlso(expression, exp.Body);
}
var parameterExpression = Expression.Parameter(typeof (Dictionary<string, object>), "x");
var lamba = Expression.Lambda<Func<Dictionary<string, object>, bool>>(expression, parameterExpression);
var res = lamba.Compile();
var counts = queryLis.Count(res);

但编者给了我一个例外从作用域"引用了类型为"System.Collections.Generic.Dictionary"的变量"x"2[System.String,System.Object]",但未定义

这样做有可能吗?

(并非例外)在其他步骤中,例如,表达式可能会询问repeatedValues[i](在for之后),但它不知道它是什么?

动态Where条件

您需要传递原始表达式所引用的相同Expression.Parameter
制作一个新的同名Expression.Parameter还不够好。

我不知道你为什么要搞Expression之类的东西。如果我理解正确的话,您实际上是在复制关系数据库的情况,每个值条目都是一行数据,其中列表示字段名。如果是这样的话,那么您还可以从数据库书中提取一页,然后使用索引。在你的第一个片段之后,你可以得到一个清理过的列表,如下所示:

// testing for duplicates
List<Dictionary<string, object>> duplicates = new List<Dictionary<string, object>>();
List<string> index = new List<string>();
foreach (var value in values)
{
    List<string> keyValues = new List<string>();
    foreach (string key in keys)
    {
        keyValues.Add(value[key].GetHashCode().ToString());
    }
    string hash = string.Join(",", keyValues.ToArray());
    if (index.Contains(hash))
        duplicates.Add(value);
    else
        index.Add(hash);
}
var cleanList = values.Except(duplicates);

EDIT:修改了示例,使其每次都将散列按相同的列顺序排列。