如何在linq中使用两个不同对象之间的并集

时间:2014-10-01 05:24:35

标签: c# linq

我想从两个不同的对象中合并数据。这两个对象只有很少的字段是常见的。

像:

class Product
{
  public int Id;
  public string Name;  
}

class Category
{
  public int Id;
  public string Name;
  public bool IsActive;
}

//Here is my query
(from p in Product
 Select p).Union(from c in Category Select c);

现在,如果我编写一个类似上面的查询,它会生成一个错误:

System.Linq.IOrderedQueryable does not contain a definition for 'Union' and the best extension method overload
'System.Linq.ParallelEnumerable.Union<TSource>(System.Linq.ParallelQuery<TSource>, System.Collections.Generic.IEnumerable<TSource>)' has some invalid arguments

如何在此处执行联盟操作?

4 个答案:

答案 0 :(得分:2)

您必须选择公共字段(但在某些枚举上,而不是在类型上),例如使用匿名对象。

var lp = new List<Product>();
var lc = new list<Category>();

var union = lp.Select(m => new { m.Id, m.Name})
              .Union(lc.Select(m => new { m.Id, m.Name}));

现在,我不确定在产品和类别之间建立联盟的真正意义,但是......这是另一个问题。

答案 1 :(得分:1)

您可以尝试下面的内容。

List<Product> products = new List<Product>();
List<Category> Categories = new List<Category>();

var results = (from pro in products select pro.Id)
             .Union (from cat in Category select cat.Id)

Example can be found here.

答案 2 :(得分:1)

您需要使用匿名对象来包含公共属性:

 var products = Product.Select(p => new {p.Id, p.Name});
 var categories = Category.Select( c=> new {c.Id, c.Name});
 var items = products.Union(categories);

或者,使用公共基类:

class Product
{
   public int Id;
   public string Name;  
}

class Category : Product
{
   public bool IsActive;
}

var products = Product.Union(Category.Cast<Product>());

Product不必是公共基类,可以使用第三个类作为基类)


UPDATE:如果你想返回Product中不存在的属性(在这种情况下,union有点奇怪),那么你应该使用匿名类型:

var products = Product.Select(p => new {p.Id, p.Name, IsActive = false});
var categories = Category.Select(c => new {c.Id, c.Name, c.IsActive});
var items = products.Union(categories);

答案 3 :(得分:0)

对于需要此功能但实际上想要枚举对象的任何人,都有一种方法。正如@eren-ersönmez所说的,您可以使用基类进行合并。

诀窍是记住.net中所有内容的基类都是对象。

因此您可以这样做:

var all = competitors.Cast<object>().Union(features.Cast<object>())

var all = competitors.Select(i => (object)i).Union(features.Select(i => (object)i))