Я пытаюсь заставить GroupJoin работать с несколькими неизвестными ключами с помощью LINQ.LINQ Composite Key GroupJoin с ключами, неизвестными во время компиляции
Я видел решения с анонимными типами, но ключи всегда были заранее определены. В моем случае они определены пользователем, поэтому я не буду знать эту информацию во время компиляции. Я попытался использовать список ключевых значений и массив ключевых значений, но они никогда не совпадают.
Так ... это работает как шарм:
Func<Component, string> getKeyValue = x => x.Attributes //from attributes
.Single(a => a.Name == _keyAttribute) //selects the key attribute
.Value; //gets attribute value
var leftJoin = source.GroupJoin(target, //join
getKeyValue, //on the same
getKeyValue, //condition
(src, corresp) => new
{
src,
corresp
})
.SelectMany(z => z.corresp.DefaultIfEmpty()
.Select(tgt => new { z.src, tgt })) //selects matching
.ToList(); //source and target
, но это не делает:
Func<Component, List<string>> getKeyValues = x => x.Attributes //from attributes
.Where(a => _keyAttributes.Contains(a.Name)) //selects key attributes
.OrderBy(a => a.Name) //order them by name
.Select(a => a.Value) //gets attributes' values
.ToList();
var leftJoin = source.GroupJoin(target, //join
getKeyValues, //on the same
getKeyValues, //condition
(src, corresp) => new
{
src,
corresp
})
.SelectMany(z => z.corresp.DefaultIfEmpty()
.Select(tgt => new { z.src, tgt })) //selects matching
.ToList(); //source and target
Если это помогает, это структура, я работаю над:
List<string> _keyAttributes;
List<Component> source;
List<Component> target;
[DataContract]
public class Component
{
[DataMember]
public List<Attribute> Attributes { get; set; }
public Component()
{
new List<Attribute>();
}
}
[DataContract]
public class Attribute
{
[DataMember]
public string Name { get; set;}
[DataMember]
public string Value { get; set;}
}
Есть ли способ решить эту проблему с помощью библиотеки LINQ или мне нужен мой собственный метод расширения GroupJoin?
Не думал о соединении значений. Так как они все струны, это работает. Я согласен с вами в том, что это не обязательно хороший способ сделать это, но я думаю, что это сработает. Не с запятой, а с уникальной комбинацией символов. Спасибо! –
Думая лучше, я останусь с решением реализации EqualityComparer для списка или T [] и передав его в качестве дополнительного аргумента GroupJoin. –
IEqualityComparer - это путь! Спасибо! –