Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无需for循环即可高效地删除数据_C#_Linq - Fatal编程技术网

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。它应该基于其他列表