从实体框架中删除单个记录?

use*_*476 184 c# sql-server entity-framework

我在实体框架中有一个SQL Server表,名为employ一个名为的单个键列ID.

如何使用Entity Framework从表中删除单个记录?

mt_*_*erg 344

没有必要首先查询对象,您可以通过其id将其附加到上下文.像这样:

var employer = new Employ { Id = 1 };
ctx.Employ.Attach(employer);
ctx.Employ.Remove(employer);
ctx.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

或者,您可以将附加条目的状态设置为已删除:

var employer = new Employ { Id = 1 };
ctx.Entry(employer).State = EntityState.Deleted;
ctx.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

  • 或者,`ctx.Entry(雇主).State = EntityState.Deleted` (83认同)
  • 这只有在关系被定义为删除级联时才有效.否则上面的代码将在FK异常时失败. (12认同)
  • @mt_serg,我正在向前看3步.什么时候你真的不得不从数据库中删除这么简单的记录?通常,您正在处理包含FK关系的更复杂的记录.因此我的评论. (6认同)
  • @PaulZahra:有时你有一个来自其他查询或来源的ID列表,你需要删除一个.这种方式可以通过ID删除,而不是仅仅为了删除它们而加载对象.您知道,这就是DELETE语句在SQL中的正常工作方式. (4认同)
  • @IanWarburton第2和第3行(附加和删除) (2认同)

Man*_*eld 77

您可以使用SingleOrDefault获取符合条件的单个对象,然后将其传递给RemoveEF表的方法.

var itemToRemove = Context.Employ.SingleOrDefault(x => x.id == 1); //returns a single item.

if (itemToRemove != null) {
    Context.Employ.Remove(itemToRemove);
    Context.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是好方法,因为你是从数据库中选择所有字段的! (4认同)
  • @Ali,杰克 - 但我认为这是首选,因为它首先检查您尝试删除的数据是否确实存在,这可以防止任何麻烦.接受的答案没有这样的检查. (4认同)
  • 这是更好的方法.想一想.如果约翰史密斯试图移除一个id = 1的项目,Susie Smith在30秒前删除但约翰不知道怎么办?在这种情况下你需要点击数据库. (4认同)
  • @Yusha为什么?在这两种情况下,结果都是记录消失了。我们真的在乎是现在还是30秒钟前发生这种情况?跟踪某些比赛条件并不是很有趣。 (3认同)
  • 这就是我这样做的方式. (2认同)
  • @9Rune5 是的,作为开发人员,我们绝对**关心**数据库中发生的事情,无论是 30 秒前还是 0.0003 毫秒前。这些数据可能非常敏感。我们需要知道谁做了什么以及为什么。在我看来,安全总比后悔好。请注意,我**不是**说你的观点无效。我只是为我的案子辩护,为什么我会使用上述作为解决方案 (2认同)

Ale*_*x G 13

  var stud = (from s1 in entities.Students
            where s1.ID== student.ID
            select s1).SingleOrDefault();

  //Delete it from memory
  entities.DeleteObject(stud);
  //Save to database
  entities.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

  • `FirstOrDefault` 是危险的。要么你知道只有一个(所以使用`SingleOrDefault`),或者有多个,并且应该在循环中完成。 (2认同)

Sam*_*ach 8

Employer employer = context.Employers.First(x => x.EmployerId == 1);

context.Customers.DeleteObject(employer);
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)


Baq*_*qvi 6

我在 LINQ 中使用实体框架。以下代码对我有帮助;

1- 对于多条记录

 using (var dbContext = new Chat_ServerEntities())
 {
     var allRec= dbContext.myEntities;
     dbContext.myEntities.RemoveRange(allRec);
     dbContext.SaveChanges();
 }
Run Code Online (Sandbox Code Playgroud)

2- 对于单条记录

 using (var dbContext = new Chat_ServerEntities())
 {
     var singleRec = dbContext.ChatUserConnections.FirstOrDefault( x => x.ID ==1);// object your want to delete
     dbContext.ChatUserConnections.Remove(singleRec);
     dbContext.SaveChanges();
 }
Run Code Online (Sandbox Code Playgroud)


Lat*_*nis 5

只是想贡献我反复使用的三种方法。

方法一:

var record = ctx.Records.FirstOrDefault();
ctx.Records.Remove(record);
ctx.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

方法二:

var record = ctx.Records.FirstOfDefault();
ctx.Entry(record).State = EntityState.Deleted;
ctx.SaveChanges();
ctx.Entry(record).State = EntityState.Detached;
Run Code Online (Sandbox Code Playgroud)

我更喜欢使用方法 2 的原因之一是因为在将 EF 或 EFCore 设置为 的情况下QueryTrackingBehavior.NoTracking,这样做更安全。

然后是方法3:

var record = ctx.Records.FirstOrDefault();
var entry = ctx.Entry(record);
record.DeletedOn = DateTimeOffset.Now;
entry.State = EntityState.Modified;
ctx.SaveChanges();
entry.State = EntityState.Detached;
Run Code Online (Sandbox Code Playgroud)

这通过设置记录的属性来利用软删除方法DeletedOn,并且仍然能够保留记录以供将来使用,无论将来使用什么。基本上,将其放入回收站


另外,对于方法 3,不要将整个记录设置为被修改:

entry.State = EntityState.Modified;
Run Code Online (Sandbox Code Playgroud)

您还可以仅设置DeletedOn修改后的列:

entry.Property(x => x.DeletedOn).IsModified = true;
Run Code Online (Sandbox Code Playgroud)