Linq-запрос, возвращающий дубликаты

1

Итак, у меня есть две таблицы данных, взятые из одного источника данных ODBC. У одного есть строки для продаж (Estado = 'VENTAS'), а другой для Estado = 'EXIST' (база данных создает пары строк для каждой продажи, одна указывает информацию о продаже, а другая - информацию о движении акций с депозита магазина, поэтому в чтобы узнать, какой магазин сделал продажу, мне нужно сопоставить каждую строку VENTAS с соответствующей строкой EXIST [по полю "Documento" ID] и получить значение "Deposito" из строки Exist).

Я построил этот запрос, чтобы сделать это (драйвер ODBC, который я использую, не позволяет присоединяться, поэтому делать это в Linq было следующим лучшим)

            DataTable dtResult = new DataTable();

            dtResult.Columns.Add("Documento", typeof(Int64)); 
            dtResult.Columns.Add("Fecha", typeof(DateTime));
            dtResult.Columns.Add("Articulo", typeof(string));
            dtResult.Columns.Add("Deposito", typeof(string));
            dtResult.Columns.Add("ImpDMn", typeof(decimal));
            dtResult.Columns.Add("Cantidad", typeof(decimal));
            dtResult.Columns.Add("Partida", typeof(string));

            var result = from dataRows1 in VentasDT.AsEnumerable() //VentasDT is the DataTable with the VENTAS data
                         join dataRows2 in ExistDT.AsEnumerable() // ExistDT is the DataTable with the EXIST data
                         on dataRows1.Field<Int64>("Documento") equals dataRows2.Field<Int64>("Documento")
                         select dtResult.LoadDataRow(new object[]
         {
            dataRows1.Field<Int64>("Documento"),
            dataRows1.Field<DateTime>("Fecha"),
            dataRows1.Field<string>("Articulo"),
            dataRows2.Field<string>("Deposito"),
            dataRows1.Field<decimal>("ImpDMn"),
            dataRows1.Field<decimal>("Cantidad"),
            dataRows1.Field<string>("Partida"),
          }, false);
            result.CopyToDataTable();

и он работает, но по какой-то причине он дублирует некоторые строки. Я проверил строки, которые были дублированы, и они идентичны друг другу. Их номера документов равны (и есть только одна VENTAS и одна строка EXIST на номер Documento, в том числе для этих дубликатов), поэтому я не знаю, почему они дублируются. Я проверил исходные Datatables, с которыми я соединяюсь, и аналогично, для дубликатов есть только одна соответствующая строка. Таблица EXIST больше, чем таблица VENTAS (она также записывает переводы между магазинами, которые не являются продажами), но объединенная таблица больше, чем (хотя и не такая большая, как оба)

VENTAS: 85123
EXIST: 116857
JOIN: 141287

Что-то не так с моим запросом? Должен ли я включать какое-либо предложение GROUP BY или.Distinct или эта структура (которая, насколько я видел, должна имитировать левое соединение), была достаточной?

  • 0
    Могут ли записи, представляющие переносы в таблице EXIST иметь свое поле Documento равным полю Documento от VENTAS ?
  • 0
    Нет. Передачи имеют свое собственное уникальное значение Documento, для которого в таблице Ventas не будет найдено никакой обратной величины, и, насколько я видел, каждый дубликат в объединяемой таблице имеет значение Documento, которое отображается в исходной таблице Ventas (следовательно, не перевод) ..
Теги:
linq

1 ответ

1
Лучший ответ

Поскольку единственная причина, по которой вы делаете это соединение, - это получить значение полей "Deposito" из ExistDT, вы можете заменить соединение поиском по словарю. Вот как вы можете это сделать:

var depositoPorDocumento = ExistDT.AsEnumerable().ToDictionary(
    dr => dr.Field<Int64>("Documento"),
    dr => dr.Field<string>("Deposito")
);
foreach (var vr in VentasDT.AsEnumerable()) {
    Int64 id = Field<Int64>("Documento");
    string deposito;
    if (!depositoPorDocumento.TryGetValue(id, out deposito)) {
        continue;
    }
    dtResult.LoadDataRow(new object[]
     {
        id,
        vr.Field<DateTime>("Fecha"),
        vr.Field<string>("Articulo"),
        deposito,
        vr.Field<decimal>("ImpDMn"),
        vr.Field<decimal>("Cantidad"),
        vr.Field<string>("Partida"),
      }, false);
}
result.CopyToDataTable();
  • 0
    Ваше решение дает мне много синтаксических ошибок: нет определения и нет метода расширения для (...) в ExistTD.ToDictionary (); Оператор foreach не может работать с Datatable (...) на foreach (var vr в VentasDT; недопустимые аргументы для! depositoPorDocumento.TryGetValue (id, out deposito) ...?
  • 0
    @ConnorU Я не был уверен, что это были за VentasDT и ExistTD , поэтому я пропустил .AsEnumerable() . Я добавил их обратно, посмотреть, если это компилируется.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню