C# 根据条件从列表中删除项目
我有一个这样的结构:C# 根据条件从列表中删除项目,c#,.net,entity-framework,linq,C#,.net,Entity Framework,Linq,我有一个这样的结构: public struct stuff { public int ID; public int quan; } 并且要删除ID为1的产品。 我目前正在尝试: prods.Remove(new stuff{ prodID = 1}); 它不起作用了 多亏了ALL您只能删除您引用的内容。因此,您必须搜索整个列表: stuff r; foreach(stuff s in prods) { if(s.ID == 1) { r = s;
public struct stuff
{
public int ID;
public int quan;
}
并且要删除ID
为1的产品。我目前正在尝试:
prods.Remove(new stuff{ prodID = 1});
它不起作用了
多亏了ALL您只能删除您引用的内容。因此,您必须搜索整个列表:
stuff r;
foreach(stuff s in prods) {
if(s.ID == 1) {
r = s;
break;
}
}
prods.Remove(r);
或
for(int i=0;i
使用linq:
prods.Remove( prods.Single( s => s.ID == 1 ) );
也许您甚至想使用SingleOrDefault()
并检查元素是否存在
编辑:由于
stuff
是一个结构,SingleOrDefault()
将不会返回null。但它将返回默认值(stuff),其ID为0。如果普通stuff对象的ID为0,则可以查询此ID:
var stuffToRemove = prods.SingleOrDefault( s => s.ID == 1 )
if( stuffToRemove.ID != 0 )
{
prods.Remove( stuffToRemove );
}
如果您有LINQ:
var itemtoremove = prods.Where(item => item.ID == 1).First();
prods.Remove(itemtoremove)
prods.Remove(prods.Single(p=>p.ID==1))代码>
您不能在foreach中修改集合,正如Vincent建议的那样,您可以使用Linq
var prod = from p in prods
where p.ID != 1
select p;
如果您的收藏类型是列表
,那么最好的方法可能是:
prods.RemoveAll(s => s.ID == 1)
这只对列表进行一次遍历(迭代),因此应该比其他方法更有效
如果您的类型更一般地是ICollection
,那么如果您关心性能,编写一个简短的扩展方法可能会有所帮助。如果没有,那么您可能可以使用LINQ(调用Where
或Single
)。对于那些希望使用实体框架将其从数据库中删除的人,这里有一个解决方案:
prods.removehere(s=>s.ID==1)代码>
以及扩展方法本身:
using System;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
namespace LivaNova.NGPDM.Client.Services.Data.Extensions
{
public static class DbSetExtensions
{
public static void RemoveWhere<TEntity>(this DbSet<TEntity> entities, Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
var records = entities
.Where(predicate)
.ToList();
if (records.Count > 0)
entities.RemoveRange(records);
}
}
}
使用系统;
使用System.Linq;
使用System.Linq.Expressions;
使用Microsoft.EntityFrameworkCore;
命名空间LivaNova.NGPDM.Client.Services.Data.Extensions
{
公共静态类DbSetExtensions
{
公共静态void RemoveWhere(此DbSet实体、表达式谓词)where tenty:class
{
var记录=实体
.Where(谓词)
.ToList();
如果(records.Count>0)
实体(记录);
}
}
}
另外,这模拟了实体框架的DB集合不可用的方法RemoveAll()
。在列表上使用find或findIndex函数而不是在列表中循环不是更快吗?您不能修改正在使用的集合iterating@Rob,对于列表,find应该是相同的。@Graphain-oops@Rob,是的,查找可能更好。你可以将你的where
查询作为参数放在First()中,或者你可以用First
替换where
,相当肯定Remove(null)抛出一个异常,排除SingleOrDefault所在的位置。@Graphain:我为你添加了一个示例,或者如果(stuff ToRemove!=默认值(stuff))
。Single会比first慢,但它可以保证您没有相同ID的重复产品,这可能是您要检查的内容。这不会删除对象。如果您指定likeprods=prods.Where(p!=1)。ToList()
您更接近了,但这不会修改作为参数提供给您的列表。无法接受此答案,因为IList没有RemoveAll。主题启动程序没有指定他/她拥有的内容:list或IList。“不能”?哈哈。别学究了。即使作者使用的是IList,RemoveAll也很难实现。如何将类型转换为list((list)prods)。RemoveAll(s=>s.ID==1)
prods.Remove(prods.Find(x => x.ID == 1));
using System;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
namespace LivaNova.NGPDM.Client.Services.Data.Extensions
{
public static class DbSetExtensions
{
public static void RemoveWhere<TEntity>(this DbSet<TEntity> entities, Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
var records = entities
.Where(predicate)
.ToList();
if (records.Count > 0)
entities.RemoveRange(records);
}
}
}