我无法有效地选择我需要显示的信息。希望其他人更好地了解如何解决这个问题。
鉴于以下数据结构,
public class Department
{
public int ID { get; set; }
public string Name { get; set; }
public IList<Product> Products{ get; set; }
}
public class Product
{
public int ID { get; set; }
public string Name { get; set; }
}
并给出以下数据
Department1 =
{
Id=1,
Name="D1",
Products = {new Product{Id=1, Name="Item1"}, new Product{Id=2, Name="Item2"}
}
Department2 =
{
Id=2,
Name="D2",
Products = {new Product{Id=2, Name="Item2"}, new Product{Id=3, Name="Item3"}
}
如何选择“Item2”对于“D1”和“D2”都是通用的?
我尝试过使用交集查询,但似乎希望两个延迟查询执行计划相交,而不是两个IEnumerable列表或IList。
非常感谢任何帮助。
编辑:通过努力保持简单,我似乎并不十分精确。
我有一个部门列表,每个部门都包含一个产品列表。根据这些列表,如何根据特定条件选择其他产品列表。在这个例子中我的标准是我只想选择我所有部门中存在的产品。我只想要与所有元素相交的数据。
答案 0 :(得分:1)
我的Intersect功能正常运行:
Department department1 = new Department
{
Id = 1,
Name = "D1",
Products = new List<Product> () { new Product { Id = 1, Name = "Item1" }, new Product { Id = 2, Name = "Item2" } }
};
Department department2 = new Department
{
Id = 2,
Name = "D2",
Products = new List<Product>() { new Product { Id = 2, Name = "Item2" }, new Product { Id = 3, Name = "Item3" } }
};
IEnumerable<Product> products = department1.Products.Intersect(department2.Products, new ProductComparer());
foreach (var p in products)
{
Console.WriteLine(p.Name);
}
(适用编辑)强>
public class ProductComparer : IEqualityComparer<Product>
{
public bool Equals(Product x, Product y)
{
return x.Name == y.Name && x.Id == y.Id;
}
public int GetHashCode(Product obj)
{
return obj.Id.GetHashCode() ^ obj.Name.GetHashCode();
}
}
答案 1 :(得分:1)
如果您想使用Linq,那么您可以展平Products集合并将每个集合与父部门对象相关联(因此您拥有(Product,Department)对的集合),然后在Product上重新分组。
var sharedItems = new[] { department1, department2 }
.SelectMany(d => d.Products, (dep, prod) => new { Department = dep, Product = prod })
.GroupBy(v => v.Product)
.Where(group => group.Count() > 1);
此查询的结果是IGroupings的枚举,其中密钥是产品,并包含具有该产品的部门。
答案 2 :(得分:1)
// Get a list of all departments.
IEnumerable<Department> departments = GetAllDepartments();
// Get a list of all products.
var products = departments.SelectMany(d => d.Products).Distinct();
// Filter out all products that are not contained in all departments.
var filteredProducts = products.
Where(p => departments.All(d => d.Products.Contains(p)));
如果合并两个查询,则会得到以下结果。
var filteredProducts = departments.
SelectMany(d => d.Products).
Distinct().
Where(p => departments.All(d => d.Products.Contains(p)));
答案 3 :(得分:0)
也许我不完全理解这个问题,但这会有用吗?
var commonProducts = new List<Product>();
Department1.Products.ForEach(delegate(Product product)
{
if (Department2.Products.Contains(product))
{
commonProducts.Add(product);
}
});
答案 4 :(得分:0)
使用SelectMany生成产品/部门对的扁平列表(可能在匿名类中),然后使用GroupBy按产品名称分组(并处理同一部门中同一产品的多个实例)。
如果我以后有机会,会扩大。
答案 5 :(得分:0)
将每个部门投射到IEnumerable<Product>
。
汇总产品列表 - 使用第一个作为起点,并在剩余列表中使用Intersect。
List<Product> commonProducts = departments
.Select(d => d.Products.AsEnumerable() )
.Aggregate( (soFar, nextList) => soFar
.Intersect(nextList, productComparer) )
.ToList()
你必须实现一个ProductComparer来绕过引用相等 - 如果Product是一个struct,你就不必这样做了。
答案 6 :(得分:-1)
LINQ查询语法更适合这些类型的查询:
var q = from p1 in Department1.Products
join p2 in Department2.Products
on p1.Id equals p2.Id
select p1;
foreach (Product p in q) Console.WriteLine(p.Name);