1

我很确定这属于“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);
    }
}
4

2 回答 2

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);
于 2012-11-09T07:13:45.547 回答
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();
    }
}
于 2012-11-09T06:03:41.817 回答