Linq не равен возвращению всех значений в сетке данных wpf - PullRequest
0 голосов
/ 13 марта 2019

Доброе утро. У меня есть список "изменений" , из которого я получаю данные из 2 таблиц данных, в результате чего "Элемент" из данных 1 равен "ItemCode" из данных 2 как показано ниже.

            var changes = (from dr1 in dtItemSicorax.AsEnumerable()
                           from dr2 in dtItemCloud.AsEnumerable()
                           where dr1.Field<string>("Item") == dr2.Field<string>("ItemCode")
                       let sum = dtItemSicorax.AsEnumerable().Where(x => x.Field<string>("Item") == dr2.Field<string>("ItemCode")).Sum(dr => dr.Field<decimal>("Quantity"))
                       select new
                       {
                           ID = dr2.Field<int>("ID"),
                           ItemName = dr2.Field<string>("ItemName"),
                           ItemCode = dr2.Field<string>("ItemCode"),
                           Qty = dr2.Field<int>("Qty"),
                           UpdatedQty = dr2.Field<int>("Qty") - sum,
                           ItemCodeName = dr1.Field<string>("Item"),
                           ItemQuantity = dr2.Field<int>("Qty") - sum,
                           InvoiceDate = dr1.Field<DateTime>("InvoiceDate"),
                           Sum = sum * -1,
                       }).GroupBy(x => x.ItemCodeName).Select(x => x.First()).ToList();

Это работает нормально. Сейчас я создаю еще один список, в котором я хочу получить данные из 2 таблиц данных, в соответствии с которыми «Item» из таблицы данных 1 равен , что не равно «ItemCode» из таблицы данных 2 .

Я использую следующий код:

            var sicochanges = (from dr1 in dtItemSicorax.AsEnumerable()
                               from dr2 in dtItemCloud.AsEnumerable()
                               where dr1.Field<string>("Item") != dr2.Field<string>("ItemCode")
                           let sumzero = 0
                           select new
                           {
                               ID = dr2.Field<int>("ID"),
                               ItemName = dr1.Field<string>("Item"),
                               ItemCode = dr1.Field<string>("Item"),
                               Qty = sumzero,
                               UpdatedQty = sumzero - Convert.ToInt32(dr1.Field<decimal>("Quantity")),
                               ItemCodeName = dr1.Field<string>("Item"),
                               ItemQuantity = Convert.ToInt32(dr1.Field<decimal>("Quantity")),
                               InvoiceDate = dr1.Field<DateTime>("InvoiceDate"),
                               Sum = sumzero - Convert.ToInt32(dr1.Field<decimal>("Quantity")),
                           }).GroupBy(x => x.ItemCode).Select(x => x.First()).ToList();

Список «sicochanges» возвращает все элементы из таблиц данных вместо только тех «Item» из данных 1 , которые равны «ItemCode» из данных datatable 2 .

РЕДАКТИРОВАТЬ 1

В Datatable 1 у меня есть элемент CADMIXAUTR06850, которого нет в Datatable 2. В Datatable 3 я пытаюсь отобразить все, что в них не распространено. Но datatable 3 отображает все элементы, как показано на рисунке.

enter image description here

Где я ошибаюсь в своем linq?

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 18 марта 2019

Вам нужно левое соединение, чтобы сопоставить значения Item и ItemCode.См. этот ответ со следующим кодом

List<string> inList1ButNotList2 = (from o in list1
                               join p in list2 on o equals p into t
                               from od in t.DefaultIfEmpty()
                               where od == null
                               select o).ToList<string>();

Важная строка здесь where od == null, которая получает элементы, которые не соответствуют, where != null будет получать элементы, которые соответствуют.

Microsoft также имеет примеров объединений

Попутно было бы неплохо присвоить совпадающим столбцам одно и то же имя.

0 голосов
/ 13 марта 2019

Я не понял вашего вопроса, но я пытаюсь упростить ваш вопрос;

Здесь у нас есть примеры данных;

var d1 = new Dictionary<int, string>() { { 1, "a" }, { 2, "b" }, { 3, "c" }, };
var d2 = new Dictionary<int, string>() { { 1, "x" }, { 2, "y" }, { 3, "z" }, };

Первый запрос;

var query1 = (
    from _d1 in d1
    from _d2 in d2
    where _d1.Key == _d2.Key
    let s = 0
    select new { k1 = _d1.Key, v1 = _d1.Value, k2 = _d2.Key, v2 = _d2.Value, }
);

var group1 = query1.GroupBy(x => x.v1);
var result1 = group1.Select(x => x.First()).ToList();

Второй запрос;

var query2 = (
    from _d1 in d1
    from _d2 in d2
    where _d1.Key != _d2.Key
    let s = 0
    select new { k1 = _d1.Key, v1 = _d1.Value, k2 = _d2.Key, v2 = _d2.Value, }
);

var group2 = query2.GroupBy(x => x.k1);
var result2 = group2.Select(x => x.First()).ToList();
  • При первом запросе вам не нужны секции GroupBy и Select.ToList достаточно.У query1 и result1 одинаковые выходные данные.

  • 2-й запрос выполняет внешнее соединение и выбирает только первые элементы групп.Он выбирает все элементы d1, но внешнее объединяет элементы d2.Он выбирает 1-2, 2-1, 3-1.Я предполагаю, что вы понимаете, почему он выбирает эти значения.

  • Если в ваших записях сетки данных нет кодов элементов с одинаковым именем элемента, не имеет значения, группируете ли вы свои данные по номеру элемента или имени элемента.

Надеюсь, это поможет вам.

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