2016-11-16 42 views
0

我试图合并两个列表。我经常这样做成功的时候我已经合并类似ProductsList1.Product.IdProductList2.Product.Id,但是在这种情况下,它更像是ProductsList.Product.IdProductCategoriesList.ProductCategory.ProductId。第三级属性是什么让我!LINQ的 - 通过性能儿童相交2所列出对象

// LIST OF PRODUCTS IN RESULT SETS 
    List<Product> products = new List<Product>(); 
    products.Add(new Product() { Id = 1 }); 
    products.Add(new Product() { Id = 2 }); 

    // LIST OF ALL PRODUCTS AND THEIR CATEGORY TAXONOMIES 
    List<ProductCategory> allProductCategories = new List<ProductCategory>(); 
    allProductCategories.Add(new ProductCategory() { ProductId = 1, CategoryUid = 101, ParentCategoryUid = 30 }); 
    allProductCategories.Add(new ProductCategory() { ProductId = 1, CategoryUid = 30, ParentCategoryUid = 2 }); 
    allProductCategories.Add(new ProductCategory() { ProductId = 1, CategoryUid = 2, ParentCategoryUid = 1 }); 
    allProductCategories.Add(new ProductCategory() { ProductId = 3, CategoryUid = 101, ParentCategoryUid = 43 }); 
    allProductCategories.Add(new ProductCategory() { ProductId = 3, CategoryUid = 43, ParentCategoryUid = 8 }); 
    allProductCategories.Add(new ProductCategory() { ProductId = 3, CategoryUid = 8, ParentCategoryUid = 1 }); 

    // NEED TO MERGE THE 2ND LIST INTO THE 1ST BY PRODUCTID VIA SQL EQUIV INNER JOIN 
    // END RESULT SHOULD BE products list has 2 objects. one object has 1 list product category with 3 child objects 
    // THIS IS THE CLOSEST I GOT 
    products.Select(x => x.Id).Intersect(allProductCategories.Select(a => a.ProductId).ToList()); 
} 

public class Product 
{ 
    private int _id; 
    private List<ProductCategory> _productCategories; 

    public int Id 
    { 
     get { return _id; } 
     set { _id = value; } 
    } 

    public List<ProductCategory> ProductCategories 
    { 
     get { return _productCategories; } 
     set { _productCategories = value; } 
    } 
} 

public class ProductCategory 
{ 
    private int _productId; 
    private int _categoryUid; 
    private int _parentCategoryUid; 

    public int ProductId 
    { 
     get { return _productId; } 
     set { _productId = value; } 
    } 

    public int CategoryUid 
    { 
     get { return _categoryUid; } 
     set { _categoryUid = value; } 
    } 

    public int ParentCategoryUid 
    { 
     get { return _parentCategoryUid; } 
     set { _parentCategoryUid = value; } 
    } 
} 
+0

第一个和第二个列表不是同一类型,因此您如何计划合并它们?你试图达到什么样的最终结果,即什么类型的列表? –

+0

好的,我看到你在代码块中继续提出你的问题作为评论。如果你将来不这样做,可能是最好的。这就是说,从你的评论中我不清楚最终的结果应该是什么。 –

回答

0
// LIST OF PRODUCTS IN RESULT SETS 
List<Product> products = new List<Product> { 
    new Product() {Id = 1, ProductCategories = new List<ProductCategory>()}, 
    new Product() {Id = 2, ProductCategories = new List<ProductCategory>()} 
}; 

// LIST OF ALL PRODUCTS AND THEIR CATEGORY TAXONOMIES 
List<ProductCategory> allProductCategories = new List<ProductCategory> 
{ 
    new ProductCategory() {ProductId = 1, CategoryUid = 101, ParentCategoryUid = 30}, 
    new ProductCategory() {ProductId = 1, CategoryUid = 30, ParentCategoryUid = 2}, 
    new ProductCategory() {ProductId = 1, CategoryUid = 2, ParentCategoryUid = 1}, 
    new ProductCategory() {ProductId = 3, CategoryUid = 101, ParentCategoryUid = 43}, 
    new ProductCategory() {ProductId = 3, CategoryUid = 43, ParentCategoryUid = 8}, 
    new ProductCategory() {ProductId = 3, CategoryUid = 8, ParentCategoryUid = 1} 
}; 

// General logic going on here: 
// Add all ProductCategory where the ProductID is equal 
// to the Prdoduct.ID to the current Product.ProductCategories 
products.ForEach(pr=> 
    allProductCategories.Where(pC=> 
     pC.ProductId.Equals(pr.Id)).ToList().ForEach(pC=> 
      pr.ProductCategories.Add(pC))); 

// products.ToList().ForEach(x=>Console.WriteLine(x.ProductCategories.Count)); 

输出:


我不知道使用交叉方法是否有更简单的方法,但是这个方法确实有效!

根据documentation(使用Enumerable.Intersect),您需要使用多种类型实现自定义IEqualityComparer。因此,目前不可能做这样的事情,或者简单地采用比我当前的解决方案更多的代码行。

如果你想知道更多关于Enumerable.Intersect,我建议访问dotnetperls.com

2

下面的查询将做的工作:

var result = products.Join(allProductCategories, p => p.Id, 
           pc => pc.ProductId, (p, pc) => new { p, pc}) 
          .GroupBy(x => x.p.Id) 
          .Select(x => new Product{ Id = x.Key, ProductCategories = x.Select(y => y.pc).ToList()}); 

要求:

  • 从两个不同的名单,其中有共同的标识获取数据,并创建一个合并版本,其中包含父代Product的Id以及所有匹配的行ProductCategory

说明:

  • 内加入的ID两个列表
  • GROUPBY ProductId来汇总ProductCategory数据
  • 在单独收集,其中ID是关键,数据选择它们是所有集合汇总/分组结果

您可以使用Linqpad和result.Dump()运行它,将提供最终结果的清晰视图t

+0

我稍微遵循这个解决方案,但我很难得到结果的类型列表 Paul

+0

现在检查,我编辑了响应产生'IEnumerable '作为回应,早些时候我创建了一个IEnumerble ',这是一个非常小的变化 –