2013-07-09 4 views
1

Я написал следующий запрос linq, но я не получаю ожидаемого результата. Мой ожидаемый результат - это все подходящие записи bettween lst и list, а также все несоответствующие записи из списка .Linq to object Прямое внешнее соединение

Я хочу следующий результат

а, б, в, г, д, е

public class Com : IEqualityComparer<DuplicateData> 
    { 
     public bool Equals(DuplicateData x, DuplicateData y) 
     { 
      return x.address.Equals(y.address); 
     } 

     public int GetHashCode(DuplicateData obj) 
     { 
      return obj.address.GetHashCode(); 

     } 
    } 

static void Run() 
{ 
    List<string> lst = new List<string>(); 
    lst.Add("a"); 
    lst.Add("b"); 
    lst.Add("c"); 
    lst.Add("p"); 

    List<DuplicateData> list = new List<DuplicateData>() 
    { 
     new DuplicateData{address="a"}, 
     new DuplicateData{address="a"}, 
     new DuplicateData{address="a"}, 
     new DuplicateData{address="b"}, 
     new DuplicateData{address="b"}, 
     new DuplicateData{address="c"}, 
     new DuplicateData{address="d"}, 
     new DuplicateData{address="e"}, 
     new DuplicateData{address="f"}, 
    }; 

    var dup = list.Distinct(new Com()); 
    var RightJoin = from x in dup 
        join y in lst 
        on x.address equals y 
        into right 
        from z in right 
        select new 
        { 
         UniqueAddress = z, 

        }; 

} 
+0

Что такое 'Com' ?? –

+0

Я использую пользовательский Comparar для удаления дубликата –

ответ

2

Попробуйте это следующим образом:

var RightJoin = from x in dup 
       join y in lst 
       on x.address equals y 
       into right 
       from z in right.DefaultIfEmpty(x.address) 
       select new 
       { 
        UniqueAddress = z, 
       }; 

результат (а, б, в, г, д, е)

Работа образца: http://ideone.com/MOIhZH


Объяснение

Чтобы сделать левое/правое соединение в linq, вы должны использовать метод DefaultIfEmpty, который даст результат (по умолчанию), когда не соответствует (объединенный результат пуст). Однако значение по умолчанию для строки равно null, поэтому вам необходимо предоставить значение по умолчанию из коллекции «слева», чтобы увидеть его в наборе результатов.


Альтернативный подход

Это, вероятно, более удобный подход. Вместо выбора из z и предоставления значения по умолчанию вы выберете из x.address - левую часть соединения.

var RightJoin = from x in dup 
       join y in lst 
       on x.address equals y 
       into right 
       from z in right.DefaultIfEmpty() 
       select new 
       { 
        UniqueAddress = x.address, 
       }; 
0

Это должно работать:

var res = from x in list 
      join y in lst on x.address equals y into right 
      from xy in right.DefaultIfEmpty() 
      select new { UniqueAddress = xy }; 

Результат:

{ UniqueAddress = a }, 
{ UniqueAddress = a }, 
{ UniqueAddress = a }, 
{ UniqueAddress = b }, 
{ UniqueAddress = b }, 
{ UniqueAddress = c }, 
{ UniqueAddress = null }, 
{ UniqueAddress = null }, 
{ UniqueAddress = null } 
+0

Это не исключенный результат. Мой ожидаемый результат: (a, b, c, d, e, f) –

Смежные вопросы