«Равен» в запросе на соединение использует средство сравнения по умолчанию для сравнения ключей с использованием поиска по ключам. Объединение реализовано в Enumerable.Join, и ключ может быть либо значением, либо ссылкой.
При запросе с использованием Linq для Sql ключ обычно является значением, поскольку первичные ключи обычно отображаются на типы значений. Однако, как показано в следующем коде, сравнение равно может быть либо по значению, либо по ссылке, которая всегда подходит для типа ключа:
KeyObj k1 = new KeyObj(); k1.Id = 1001;
KeyObj k2 = new KeyObj(); k2.Id = 1002;
KeyObj k3 = new KeyObj(); k3.Id = 1003;
KeyObj k4 = new KeyObj(); k4.Id = 1004;
KeyObj k5 = new KeyObj(); k4.Id = 1005;
List<Foo> foos =
new List<Foo>()
{
new Foo("o1",k1),
new Foo("o2",k2),
new Foo("o4",k5)
};
List<Bar> bars =
new List<Bar>()
{
new Bar("o2",k1),
new Bar("o3",k2),
new Bar("o4",k4),
new Bar("o5",k5)
};
var foobar = from f in foos
join b in bars on f.Ko equals b.Ko
select f.Name + " in foos joined by reference with " + b.Name + " in bars ";
foreach (var v in foobar)
{
Debug.WriteLine(v);
}
foobar = from f in foos
join b in bars on f.Name equals b.Name
select f.Name + " in foos joined by value with " + b.Name + " in bars ";
foreach (var v in foobar)
{
Debug.WriteLine(v);
}
class KeyObj { public int Id { get; set; } }
class Foo : Base
{
public Foo(string s, KeyObj ko) : base(s, ko) { }
}
class Bar : Base
{
public Bar(string s, KeyObj ko) : base(s, ko) { }
}
class Base
{
string _name = "";
public string Name { get { return _name; }}
KeyObj _ko = null;
public KeyObj Ko { get { return _ko; }}
public Base(string s, KeyObj ko)
{
_name = s;
_ko = ko;
}
}
Выходные данные:
o1 в foos, соединенных ссылкой с o2 в барах
o2 в foos, соединенных ссылкой с o3 в барах
o4 в foos, соединенных ссылкой с o5 в барах
o2 в foos, соединенных по значению с o2 в барах
o4 в foos, соединенных по значению с o4 в барах