C# LINQ中的批量删除到实体
是否有任何方法可以批量删除与LINQ或LINQ中的给定查询与实体匹配的一组对象?我能找到的唯一引用已经过时,而且迭代并手动删除所有我希望删除的对象似乎很愚蠢。我知道任何数据上下文的方法都会删除查询中的所有记录。由于删除了很多对象,因此必须进行一些优化。不过我不确定。我不确定它的效率,但您可以尝试以下方法:C# LINQ中的批量删除到实体,c#,database,linq,entity-framework,linq-to-entities,C#,Database,Linq,Entity Framework,Linq To Entities,是否有任何方法可以批量删除与LINQ或LINQ中的给定查询与实体匹配的一组对象?我能找到的唯一引用已经过时,而且迭代并手动删除所有我希望删除的对象似乎很愚蠢。我知道任何数据上下文的方法都会删除查询中的所有记录。由于删除了很多对象,因此必须进行一些优化。不过我不确定。我不确定它的效率,但您可以尝试以下方法: // deletes all "People" with the name "Joe" var mypeople = from p in myDataContext.People
// deletes all "People" with the name "Joe"
var mypeople = from p in myDataContext.People
where p.Name == "Joe";
select p;
myDataContext.People.DeleteAllOnSubmit(mypeople);
myDataContext.SubmitChanges();
var query = from c in ctx.Customers
where c.SalesPerson.Email == "..."
select c;
query.Delete();
您可以编写一个执行删除的存储过程,并从LINQ调用它。总体而言,基于集合的删除速度可能更快,但如果它影响太多记录,则可能会导致锁定问题,并且可能需要混合循环记录集合(一次可能是2000个,大小取决于数据库设计,但如果您发现基于集合的删除耗时太长,会影响表的其他使用,则2000是一个起点)执行删除操作 不久前,我写了一个由4部分组成的博客系列(Parts,and),介绍在实体框架中进行批量更新(使用一个命令) 虽然该系列的重点是更新,但您完全可以使用所涉及的原则进行删除 所以你应该能写下这样的东西:
// deletes all "People" with the name "Joe"
var mypeople = from p in myDataContext.People
where p.Name == "Joe";
select p;
myDataContext.People.DeleteAllOnSubmit(mypeople);
myDataContext.SubmitChanges();
var query = from c in ctx.Customers
where c.SalesPerson.Email == "..."
select c;
query.Delete();
您所需要做的就是实现Delete()扩展方法。有关如何
希望这有帮助我在这里看到的答案是Linq到Sql DeleteAllOnSubmit是System.Data.Linq的一部分,ITable是Linq to Sql的一部分 这不能用实体框架来完成
说到这里,我还没有一个解决方案,但是当我通过实体框架删除数据时,我将返回使用DeleteObject方法。可以在要删除的实体类的EntityCollection上或在派生的ObjectContext上调用此方法。下面是一个简单的例子:
using (var context = new DatabaseEntities())
{
// delete existing records
context.ExecuteStoreCommand("DELETE FROM YOURTABLE WHERE CustomerID = {0}", customerId);
}
NorthwindEntities db = new NorthwindEntities();
IEnumerable<Order_Detail> ods = from o in db.Order_Details
where o.OrderID == 12345
select o;
foreach (Order_Detail od in ods)
db.Order_Details.DeleteObject(od);
db.SaveChanges();
NorthwindEntities db=新的NorthwindEntities();
IEnumerable ods=从o开始,以db.Order\u详细信息为单位
其中o.OrderID==12345
选择o;
foreach(订单详细信息ods中的od)
db.Order_Details.DeleteObject(od);
db.SaveChanges();
这是一个老问题(在EF5出现之前)。对于使用EF5的任何人,都可以快速执行此操作。对于使用EF6并希望执行行SQL查询以进行删除的人:
using (var context = new DatabaseEntities())
{
// delete existing records
context.Database.ExecuteSqlCommand("DELETE FROM YOURTABLE WHERE CustomerID = @id", idParameter);
}
我会这样做:
var recordsToDelete = (from c in db.Candidates_T where c.MyField == null select c).ToList<Candidates_T>();
if(recordsToDelete.Count > 0)
{
foreach(var record in recordsToDelete)
{
db.Candidate_T.DeleteObject(record);
db.SaveChanges();
}
}
var recordsToDelete=(从db.Candidates中的c开始,其中c.MyField==null选择c);
如果(recordsToDelete.Count>0)
{
foreach(recordsToDelete中的var记录)
{
db.Candidate\u.DeleteObject(记录);
db.SaveChanges();
}
}
我不认为没有循环就可以做到这一点,因为实体框架与实体一起工作,大多数情况下,这意味着对象的收集。在本例中,我将删除记录,并将其逐个附加到结果集,然后请求将其删除。然后我有1个保存更改
using (BillingDB db = new BillingDB())
{
var recordsToDelete = (from i in db.sales_order_item
where i.sales_order_id == shoppingCartId
select i).ToList<sales_order_item>();
if(recordsToDelete.Count > 0)
{
foreach (var deleteSalesOrderItem in recordsToDelete)
{
db.sales_order_item.Attach(deleteSalesOrderItem);
db.sales_order_item.Remove(deleteSalesOrderItem);
}
db.SaveChanges();
}
}
使用(BillingDB=new BillingDB())
{
var recordsToDelete=(来自db.sales\u order\u项目中的i
其中i.sales\u order\u id==shoppingCartId
选择i.ToList();
如果(recordsToDelete.Count>0)
{
foreach(recordsToDelete中的var deleteSalesOrderItem)
{
db.sales\u order\u item.Attach(删除SalesOrderItem);
db.sales\u order\u item.Remove(删除SalesOrderItem);
}
db.SaveChanges();
}
}
这是使用EF从数据库中删除记录的最快方法。RemoveRange是在EF6中引入的,它可以删除对象列表。超级容易
var origins= (from po in db.PermitOrigins where po.PermitID == thisPermit.PermitID select po).ToList();
db.PermitOrigins.RemoveRange(origins);
db.SaveChanges();
当前EF中未实施批量操作。 这正是实体框架团队设计的方式。反编译器清楚地显示EF在内部执行的操作:
public void DeleteAllOnSubmit<TSubEntity>(IEnumerable<TSubEntity> entities)
where TSubEntity : TEntity
{
if (entities == null)
{
throw Error.ArgumentNull("entities");
}
CheckReadOnly();
context.CheckNotInSubmitChanges();
context.VerifyTrackingEnabled();
foreach (TSubEntity item in entities.ToList())
{
TEntity entity = (TEntity)(object)item;
DeleteOnSubmit(entity);
}
}
在我看来不太好看
下面是我写的一个例子,它稍微简化了一点:
void Main()
{
var ctx = this;
void DeleteTable<T>(System.Data.Linq.Table<T> tbl, bool submitChanges = false)
where T : class
{
tbl.DeleteAllOnSubmit(tbl);
if (submitChanges) ctx.SubmitChanges();
}
DeleteTable(ctx.Table1);
DeleteTable(ctx.Table2);
DeleteTable(ctx.Table3);
ctx.SubmitChanges();
}
void Main()
{
var ctx=此;
void deletetetable(System.Data.Linq.Table tbl,bool submitChanges=false)
T:在哪里上课
{
tbl.DeleteAllOnSubmit(tbl);
if(submitChanges)ctx.submitChanges();
}
删除表(ctx.Table1);
删除表(ctx.表2);
删除表(ctx.表3);
ctx.SubmitChanges();
}
如果您正在进行测试,并且需要删除很多表,那么这种语法更容易处理。换句话说,这是一些语法上的糖分,方便你使用。但请记住,EF仍然在内部和内存中循环所有对象,如果数据量很大,这可能会非常低效。这仍然会迭代匹配查询的所有元素;它只在DB上执行,而不是在代码中执行。效率更高,但离理想的解决方案还有一段距离。那么,我唯一能想到的其他方法就是使用myDataContext.ExecuteCommand(“删除…”);。这也很不理想,但它会起作用。实际上没有进行任何优化。生成的SQL枚举与查询匹配的所有对象,然后手动迭代以删除它们。当然,迭代是在数据库中进行的,而不是在代码中,但是您仍然不必要地构建一个结果集,仅仅是为了删除其内容——这比简单的“从表中删除foo=bar”要糟糕得多,后者不构建结果集,只覆盖表一次。如果有人有代码示例,那么在这里就很好了!在这里可以找到一系列扩展方法(包括批量删除):当心对EF5有依赖性,如果您使用Nuget Package manager控制台安装它,它将在不要求您安装EF5的情况下安装它。它并没有真正的帮助-我想看一个delete命令的工作示例,而不是“猜测”如何在生产代码中实现我自己的代码以及