Динамическое условие Где - PullRequest
0 голосов
/ 14 марта 2012

У меня небольшая проблема :) У меня есть список, в котором некоторые аргументы дублируются.Я должен удалить это.Я не могу использовать Distinct, потому что я должен видеть только некоторые поля (не все). Я думаю, что это отличный вариант для использования лямбда-выражений.

У меня есть объявление на моем объекте, над которым я работаю, не то же самое, ноИдея аналогична.

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"}});
}

Длина столбцов ключей всегда равна повторяемым значениям - но изменяется, некоторые длины равны 1, другие 2,3,5.Не более 5

Ключи похожи на primaryKeys в таблице базы данных.Это очень похоже.Поэтому мы ищем дубликаты в «столбцах первичных ключей» - я думаю, это хорошее сравнение.

Мы видим, что в этом примере дубликат имеет значение 5 в "column1" и значения 15 в "column2".Как я раньше говорил, я должен удалить это, но прежде чем я должен считать повторяющиеся элементы.

Я пытаюсь сделать код подобным образом (я знаю, что метод func awalys сбой, потому что (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);

Но компилятор дает мне исключительную переменную 'x' типа 'System.Collections.Generic.Dictionary`2 [System.String, System.Object]', на которую ссылается область действия'', но он не определен

Можно ли сделать это таким образом?

(Не об исключении) На другом шаге, может быть, выражение запрашивает например repeatValues ​​[i] (послеза) и он не будет знать, что это?

Ответы [ 2 ]

0 голосов
/ 14 марта 2012

Я не знаю, почему вы возитесь с 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);

РЕДАКТИРОВАТЬ: измененный пример, так что он каждый раз помещает хэш в один и тот же порядок столбцов.

0 голосов
/ 14 марта 2012

Вам нужно передать тот же Expression.Parameter, на который ссылается исходное выражение.
Создание нового Expression.Parameter с тем же именем недостаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...