我很确定这属于“UNION”情景,但我真的只是寻找解决问题的最佳方法(即使它不是UNION)。
我有一个如下所示的查询:
var query = context.AffiliateConfigurations.Where(x => x.AffiliateId == affiliateId).Select(config => new ViewModels.ConfigurationItem
{
ConfigurationId = config.AffiliateConfigurationId,
ConfigKey = config.ConfigKey,
ConfigValue = config.ConfigValue,
UpdatedDate = config.UpdatedDate,
ConfigurationType = ViewModels.ConfigurationType.Affiliate
});
我想要做的是为该查询添加更多结果。我有另一个名为SiteConfiguration的表,它具有完全相同的模式,但我只想添加来自该表的行,而原始查询中尚不存在ConfigKey。
我现在有类似下面的东西(并且它有效),但我正在寻找一种“纯粹的”LINQ方式:
var items = context.AffiliateConfigurations.Where(x => x.AffiliateId == affiliateId).Select(config => new ViewModels.ConfigurationItem
{
ConfigurationId = config.AffiliateConfigurationId,
ConfigKey = config.ConfigKey,
ConfigValue = config.ConfigValue,
UpdatedDate = config.UpdatedDate,
ConfigurationType = ViewModels.ConfigurationType.Affiliate
}).ToList();
var query = context.SiteConfigurations.Select(config => new ViewModels.ConfigurationItem
{
ConfigurationId = config.SiteConfigurationId,
ConfigKey = config.ConfigKey,
ConfigValue = config.ConfigValue,
UpdatedDate = config.UpdatedDate
});
foreach (var item in query)
{
if (items.All(x => x.ConfigKey != item.ConfigKey))
{
items.Add(item);
}
}
答案 0 :(得分:2)
所以你的问题是"I have two collections and i want to merge them.how do i exclude items from the second collection,if the item's property is matching with another item's property on the first list."
是LINQ的UNION是您在这种情况下所需要的
您需要做的就是为ConfigurationItem
class ConfigEqualityComparer : IEqualityComparer<ConfigurationItem>
{
public bool Equals(ConfigurationItem a, ConfigurationItem b)
{
if (a.ConfigKey == b.ConfigKey)
{
return true;
}
else
{
return false;
}
}
public int GetHashCode(ConfigurationItem a)
{
//do some hashing here
//int hCode = IntegerField1 ^ IntegerField2;
return hCode.GetHashCode();
}
}
这就是您所需要的。您现在可以运行UNION查询并获得预期的输出。
var comparer = new ConfigEqualityComparer();
var result = Enumerable.Union<ConfigurationItem>(items, query, comparer);
答案 1 :(得分:1)
我认为LINQ Union运算符就是你想要的。您只需要创建一个实现项目IEqualityComparer<T>
接口的类。这是一些演示代码。尝试不使用比较器的foreach
来查看包含的欺骗,或者将其删除。我在LINQPad中运行代码,如果您使用的是Visual Studio,则需要将Main
方法移动到类中并调用它。
void Main()
{
List<DataObject> set1 = new List<DataObject>();
List<DataObject> set2 = new List<DataObject>();
set1.Add(new DataObject("a"));
set1.Add(new DataObject("b"));
set1.Add(new DataObject("c"));
set1.Add(new DataObject("d"));
set1.Add(new DataObject("e"));
set2.Add(new DataObject("c"));
set2.Add(new DataObject("d"));
set2.Add(new DataObject("e"));
set2.Add(new DataObject("f"));
set2.Add(new DataObject("g"));
set2.Add(new DataObject("h"));
// try as
// foreach (DataObject d in set1.Union(set2)) {
// and dupes will be present
foreach (DataObject d in set1.Union(set2, new DOComparer())) {
Console.WriteLine(d);
}
}
// Define other methods and classes here
public class DataObject {
public DataObject(string value) {
Value = value;
}
public string Value {get;private set;}
public override string ToString() {
return Value;
}
}
public class DOComparer:IEqualityComparer<DataObject> {
public bool Equals(DataObject do1, DataObject do2) {
return do1.Value.Equals(do2.Value);
}
public int GetHashCode(DataObject d) {
return d.Value.GetHashCode();
}
}