LINQ - chování .Distinct()   otázka

C#, LINQ, ADO.NET, Databáze

Zdravím,

mám vytvořených 5 DataTable. Spojil jsem je dotazem přes LINQ a nemůžu dohledat následující chování LINQu.

1. Pokud nepoužiji na konci dotazu .Distinct() tak se mi řádky opakují (počet DataTable x počet joinů).

2. Pokud přidám k SELECTu další JOIN na DataTable, který obsahuje pouze nějaké údaje (ostatní hodnoty jsou NULL), výsledek dotazu mi vynechá nulové hodnoty, tj. v analogii na MS SQL mi vypíše INNER JOIN a nikoliv LEFT JOIN. Dle dokumentace by právě .Distinct() měl určit chování, aby se LINQ dotaz choval jako MS SQL LEFT JOIN.

Mohl bych Vás touto cestou poprosit o vysvětlení (ev. odkaz, kde to je vysvětleno jak pro blbce), proč se .Distinct() takto chová?

Pro úplnost přikládám syntaxi LINQ

// ZÁKLADNÍ DATATABLE
this.datatableVtpVlanEntry.Columns.Add("VtpVlanIndex", typeof(int));
this.datatableVtpVlanEntry.Columns.Add("VtpVlanName", typeof(string));
this.datatableMacAddressTable.Columns.Add("VtpVlanIndex", typeof(int));
this.datatableMacAddressTable.Columns.Add("HelperRelation", typeof(string));
this.datatableMacAddressTable.Columns.Add("MacAddress", typeof(string));
this.datatableBridgePortNumber.Columns.Add("HelperRelation", typeof(string));
this.datatableBridgePortNumber.Columns.Add("IfIndex", typeof(int));
this.datatableMapBridgePortToIfIndex.Columns.Add("IfIndex", typeof(int));
this.datatableMapBridgePortToIfIndex.Columns.Add("BridgePort", typeof(int));
this.datatableCorrelateIfIndexWithCorrectPortName.Columns.Add("BridgePort", typeof(int));
this.datatableCorrelateIfIndexWithCorrectPortName.Columns.Add("CorrectPortName", typeof(string));

// POKUD PŘIDÁM DO JOINU, STANE SE MI Z DOTAZU INNER JOIN
this.datatableIpNetToMediaPhysAddress.Columns.Add("IpAddress", typeof(string));
this.datatableIpNetToMediaPhysAddress.Columns.Add("MacAddress", typeof(string));


var results = (
  from tbVtpVlanEntry in this.datatableVtpVlanEntry.AsEnumerable()
  
  join tbMacAddressTable in this.datatableMacAddressTable.AsEnumerable()
      on tbVtpVlanEntry.Field<int>("VtpVlanIndex") equals tbMacAddressTable.Field<int>("VtpVlanIndex")  
  
  join tbBridgePortNumber in this.datatableBridgePortNumber.AsEnumerable()
      on tbMacAddressTable.Field<string>("HelperRelation") equals tbBridgePortNumber.Field<string>("HelperRelation")
  
  join tbMapBridgePortToIfIndex in this.datatableMapBridgePortToIfIndex.AsEnumerable()
      on tbBridgePortNumber.Field<int>("IfIndex") equals tbMapBridgePortToIfIndex.Field<int>("IfIndex")
  
  join tbCorrelateIfIndexWithCorrectPortName in this.datatableCorrelateIfIndexWithCorrectPortName.AsEnumerable()
      on tbMapBridgePortToIfIndex.Field<int>("BridgePort") equals tbCorrelateIfIndexWithCorrectPortName.Field<int>("BridgePort")
  
  // POKUD PŘIDÁM DO JOINU, STANE SE MI Z DOTAZU INNER JOIN
  join tbIpNetToMediaPhysAddress in this.datatableIpNetToMediaPhysAddress.AsEnumerable()
      on tbMacAddressTable.Field<string>("MacAddress") equals tbIpNetToMediaPhysAddress.Field<string>("MacAddress")
  
  select new
  {
      colVtpVlanIndex = tbVtpVlanEntry.Field<int>("VtpVlanIndex"),
      colVtpVlanName = tbVtpVlanEntry.Field<string>("VtpVlanName"),
      colHelperRelation = tbMacAddressTable.Field<string>("HelperRelation"),
      colMacAddress = tbMacAddressTable.Field<string>("MacAddress"),
      colIpAddress = tbIpNetToMediaPhysAddress.Field<string>("IpAddress"),
      colIfIndex = tbMapBridgePortToIfIndex.Field<int>("IfIndex"),
      colBridgePort = tbMapBridgePortToIfIndex.Field<int>("BridgePort"),
      colCorrectPortName = tbCorrelateIfIndexWithCorrectPortName.Field<string>("CorrectPortName")
  }).Distinct();

Děkuji, Petr

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Distinct v kombinaci s Inner Joinem rozhodně neudělá Outer Join.

Na tohle se typicky používá GroupJoin.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback