在我的看法中,使用entity framework删除一个对象之前需要先获取它,代码如下:
var customer = context.Customers.First(c => c.Id == 1);
context.DeleteObject(customer);
context.Savechanges();
所以我需要两次访问数据库。有更简单的方法吗?
在我的看法中,使用entity framework删除一个对象之前需要先获取它,代码如下:
var customer = context.Customers.First(c => c.Id == 1);
context.DeleteObject(customer);
context.Savechanges();
所以我需要两次访问数据库。有更简单的方法吗?
Remove
。以下是一个示例。Customer customer = new Customer () { Id = id };
context.Customers.Attach(customer);
context.Customers.Remove(customer);
context.SaveChanges();
如果您不想查询它,只需创建一个实体,然后删除它。
Customer customer = new Customer () { Id = id };
context.Customers.Attach(customer);
context.Customers.DeleteObject(customer);
context.SaveChanges();
类似问题请参考此处。
使用Entity Framework时,可以使用扩展库EntityFramework-Plus。该库可在NuGet上获取。然后您就可以编写以下内容:
// DELETE all users which has been inactive for 2 years
ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2))
.Delete();
它还可用于批量删除。
Customer customer = new Customer() { Id = 1 } ;
context.AttachTo("Customers", customer);
context.DeleteObject(customer);
context.Savechanges();
自从Entity Framework Core 7以后,你可以使用以下代码:
await context.Customers.Where(c => c.Id == 1).ExecuteDeleteAsync();
ExecuteDeleteAsync()
不会尊重变更跟踪器和事务性的SaveChanges()
。因此,您必须手动创建一个外观事务并处理提交/回滚。 - undefined我在我的一个项目中使用以下的代码:
using (var _context = new DBContext(new DbContextOptions<DBContext>()))
{
try
{
_context.MyItems.Remove(new MyItem() { MyItemId = id });
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
if (!_context.MyItems.Any(i => i.MyItemId == id))
{
return NotFound();
}
else
{
throw ex;
}
}
}
这样一来,只有在尝试删除具有指定ID的项目时发生异常时,它才会查询数据库两次。然后,如果未找到该项目,则返回有意义的消息;否则,它会将异常抛回(您可以使用不同的catch块处理不同的异常类型,使用if块添加更多自定义检查等等)。context.Remove(new Customer(Id: id)); // adds the object in "Deleted" state
context.SaveChanges(); // commits the removal
Attach()
方法-它会将对象添加到Unchanged
状态的更改跟踪器中,而Remove()
方法会将对象添加到Deleted
状态的跟踪器中。然而,最重要的是你只需要进行一次与后端的往返通信。这个答案实际上来自于Scott Allen的ASP.NET MVC 5基础课程。我想分享它,因为我认为它比已有的答案更简单直观。另外请注意,根据Scott Allen和我参加的其他培训,find方法是从数据库检索资源的优化方式,如果已经被检索过,可以使用缓存。在这段代码中,集合指的是一个对象的DBSet,对象可以是任何通用对象类型。
var object = context.collection.Find(id);
context.collection.Remove(object);
context.SaveChanges();
来自官方文档(也是我迄今为止找到的最有效的方法):
Student studentToDelete = new Student() { ID = id };
_context.Entry(studentToDelete).State = EntityState.Deleted;
await _context.SaveChangesAsync();
dwkd的答案对我在Entity Framework Core中大部分有效,除了当我看到这个异常时:
InvalidOperationException:实体类型“Customer”的实例无法被跟踪,因为已经有另一个具有{'Id'}相同键值的实例正在被跟踪。在附加现有实体时,请确保只有一个具有给定键值的实体实例被附加。考虑使用'DbContextOptionsBuilder.EnableSensitiveDataLogging'查看冲突的关键值。
为避免此异常,我更新了代码:
Customer customer = context.Customers.Local.First(c => c.Id == id);
if (customer == null) {
customer = new Customer () { Id = id };
context.Customers.Attach(customer);
}
context.Customers.Remove(customer);
context.SaveChanges();
FirstOrDefault
吗? - El Mac
Attach()
。据我所见,该方法用于在执行期间将其跟踪到数据库中。 - drethedevjs