C# 无需for循环即可高效地删除数据
我有以下课程C# 无需for循环即可高效地删除数据,c#,linq,C#,Linq,我有以下课程 public class Product { public int Id { get; set; } public string Name { get; set; } public int CategoryId { get; set; } public int SectionId { get; set; } public string VendorName { get; set; } } public class ProductToRemo
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public int SectionId { get; set; }
public string VendorName { get; set; }
}
public class ProductToRemove
{
public int CategoryId { get; set; }
public int SectionId { get; set; }
}
大体上,我有这两个类的列表,如下所示
List<Product> Products = new List<Product>()
{
new Product() { Id = 1, Name = "A", CategoryId = 11, SectionId = 6, VendorName = "ABC" },
new Product() { Id = 2, Name = "B", CategoryId = 21, SectionId = 6, VendorName = "ABC" },
new Product() { Id = 3, Name = "C", CategoryId = 13, SectionId = 8, VendorName = "ABC" },
new Product() { Id = 4, Name = "D", CategoryId = 90, SectionId = 6, VendorName = "ABC" },
new Product() { Id = 5, Name = "E", CategoryId = 25, SectionId = 9, VendorName = "ABC" },
};
List<ProductToRemove> ProductsToRemove = new List<ProductToRemove>()
{
new ProductToRemove() {CategoryId = 11, SectionId = 6, },
new ProductToRemove() {CategoryId = 90, SectionId = 6, }
};
我想从Products实例中删除CategoryId和SectionId与ProductsToRemove集合中的内容匹配的任何内容。我知道如何循环产品收集和删除匹配记录,但我想知道是否有一种方法可以使用Linq执行相同的操作,您可以将Where与任意组合使用,以实现所需的输出:
var deletion = Products
.Where(product=> ProductsToRemove
.Any(remove=> product.CategoryId == remove.CategoryId
&& product.SectionId == remove.SectionId
)
);
您可以将Where与任意选项组合使用,以实现所需的输出:
var deletion = Products
.Where(product=> ProductsToRemove
.Any(remove=> product.CategoryId == remove.CategoryId
&& product.SectionId == remove.SectionId
)
);
您可以使用Linq except方法:对于那些不介意更改数据类型的人,您可以使用Linq except方法: 如果不允许键在集合中发生冲突,则可以使用普通字典。或者实现并使用一个注释,说明HashSet是一个集合,而不是一个列表 如果键可能发生冲突,您可以使用列表字典来实现这一点 这是我的意思的一个例子
Dictionary<string, List<Product>> Products = default;
List<Product> l = default.GetOrDefault(p.id1+"<|>"+p.id2); //LinQ extension on map
l.Clear();
当然,您可以将其封装在一个类中,将其伪装成一个列表,可能还包含一个实际的列表以保持顺序。适用于那些不介意更改数据类型的人 如果不允许键在集合中发生冲突,则可以使用普通字典。或者实现并使用一个注释,说明HashSet是一个集合,而不是一个列表 如果键可能发生冲突,您可以使用列表字典来实现这一点 这是我的意思的一个例子
Dictionary<string, List<Product>> Products = default;
List<Product> l = default.GetOrDefault(p.id1+"<|>"+p.id2); //LinQ extension on map
l.Clear();
当然,您可以将其封装在一个类中,以将其伪装成一个列表,可能还包含一个实际的列表以保持顺序。可能的LINQ副本也会使用循环-这不是魔术。事实上,在这里将LINQ与GroupBy/Except或诸如此类的东西一起使用会导致比自己循环效率更低的结果。如果列表是按CategoryId、SectionId排序的,那么可能会有一个更高效的算法——当然,排序本身会消耗时间。LINQ的可能副本也会使用循环——这不是魔术。事实上,在这里将LINQ与GroupBy/Except或诸如此类的东西一起使用会导致比自己循环效率更低的结果。如果列表是按CategoryId、SectionId排序的,则可以使用更有效的算法,但排序本身会消耗时间。输出应包含3行产品ID为2、3、5的行。您的代码返回了吗?是的,这只返回了两个对象,这些对象将被删除,但我已经在ProductStoreMove中有了它们,只需删除!在开始时,输出应包含3行,产品ID为2、3、5。您的代码返回了吗?是的,这只返回了两个对象,这些对象将被删除,但我已经在ProductStoreMove中有了它们,只需删除!在开始时,可以进一步检查同一where子句中的节ID!我不想在删除时硬编码这些ID。它应该基于其他列表,可以进一步检查同一where子句中的节ID!我不想在删除时硬编码这些ID。它应该基于其他列表