我已经浏览了本网站上的问题,但没有找到与我的特定问题匹配的问题。

假设我有以下内容:

Product[] store1 = { new Product { Name = "apple", Code = 9, Code1="1" },
                   new Product { Name = "orange", Code = 4 } };

Product[] store2 = { new Product { Name = "apple", Code = 9, Code2="2" },
                   new Product { Name = "lemon", Code = 12 } };


带有:

public class Product : IEquatable<Product>
{
    public string Name { get; set; }
    public int Code { get; set; }
    public string Code1 { get; set; }
    public string Code2 { get; set; }

    public bool Equals(Product other)
    {

        //Check whether the compared object is null.
        if (Object.ReferenceEquals(other, null)) return false;

        //Check whether the compared object references the same data.
        if (Object.ReferenceEquals(this, other)) return true;

        //Check whether the products' properties are equal.
        return Code.Equals(other.Code) && Name.Equals(other.Name);
    }

    // If Equals() returns true for a pair of objects
    // then GetHashCode() must return the same value for these objects.

    public override int GetHashCode()
    {

        //Get hash code for the Name field if it is not null.
        int hashProductName = Name == null ? 0 : Name.GetHashCode();

        //Get hash code for the Code field.
        int hashProductCode = Code.GetHashCode();

        //Calculate the hash code for the product.
        return hashProductName ^ hashProductCode;
    }
}


我如何返回单个Enumerable,其中store1的数据在匹配时被store2的数据覆盖,而在非匹配时从store2插入到store1中。基本上,我正在寻找与TSQL Merge语句等效的C#。

在运行此命令的一天结束时:

foreach (var product in union)
      Console.WriteLine(product.Name + " " + product.Code + " " + product.Code1 + " " + product.Code2);


我想回来:

苹果9 1 2

橙色4

柠檬12

但是,当我运行此:

IEnumerable<Product> union = store1.Union(store2);


我得到:

苹果9 1

橙色4

柠檬12

当我运行这个:

IEnumerable<Product> union = store1.Concat(store2);


我得到:

苹果9 1

橙色4

苹果9 2

柠檬12

在此先感谢您的帮助。

最佳答案

        //
        // Summary:
        //     Produces the set union of two sequences by using the default equality comparer.
        //
        // Parameters:
        //   first:
        //     An System.Collections.Generic.IEnumerable<T> whose distinct elements form
        //     the first set for the union.
        //
        //   second:
        //     An System.Collections.Generic.IEnumerable<T> whose distinct elements form
        //     the second set for the union.
        //
        // Type parameters:
        //   TSource:
        //     The type of the elements of the input sequences.
        //
        // Returns:
        //     An System.Collections.Generic.IEnumerable<T> that contains the elements from
        //     both input sequences, excluding duplicates.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     first or second is null.
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);


由于该功能


  排除重复项。


因此,您必须为Product []编写并集函数

public static class ProductExtension
{
    public static IEnumerable<T> Union<T>(this IEnumerable<T> store1, IEnumerable<T> store2)
    {
        List<T> List = new List<T>();
        foreach (var item in store2)
        {
            if (store1.Any(n=>n.Equals(item)))
            {
                var obj = store1.First(n => n.Equals(item));
                foreach (System.Reflection.PropertyInfo pi in obj.GetType().GetProperties())
                {
                    object v1 = pi.GetValue(obj, null);
                    object v2 = pi.GetValue(item, null);
                    var value = v1;
                    if (v2 != null && (v1 == null || v1.ToString() == string.Empty) && v1 != v2)
                    {
                        value = v2;
                    }
                    pi.SetValue(obj, value, null);
                }
                List.Add(obj);
            }
            else {
                List.Add(item);
            }
        }

        foreach (var item in store1) {
            if(!store2.Any(n=>n.Equals(item))){
                List.Add(item);
            }
        }
        return List.AsEnumerable();
    }
}

08-27 16:33