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は、このようなシナリオで必要なものです

あなたがする必要があるのはあなたのための簡単なComparerクラス(IEqualityComparerインターフェースの実装)を書くことです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ユニオンオペレーターがあなたが望むものだと思います。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 に答える