所以我有这两个简单的模型
public class Blog
{
public int BlogId { get; set; }
private string _Name;
[Column("sNameColumn")]
public string Name { get { return _Name; } set { _Name = value; } }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int? blog_id { get; set; }
[ForeignKey("blog_id")]
public virtual Blog Blog { get; set; }
}
我没有在dbContext定义中做任何异常的事情。然后,我尝试做这样的事情。
db.Blogs.Remove(db.Blogs.Find(2));
db.SaveChanges();
我得到一个FK违规错误。注意FK blog_id是无效的,所以我认为EF应该处理删除,并使相应的FK Null。 你能告诉我我错过了什么吗?
答案 0 :(得分:1)
必须为EF加载实体才能处理将其外键设置为null。
var b = db.Blogs.Find(2);
db.Entry(b).Collection(b => b.Posts).Load();
db.Blogs.Remove(b);
db.SaveChanges();
答案 1 :(得分:1)
请记住,Entity Framework只能更新已加载的实体。
当然,有些方法可以通过原始SQL语句更新数据库记录,也可以通过EF执行,但这不是EF的核心,而是ORM。
因此,如果您只想使用EF,您别无选择。您必须明确地在Blogs
中加载集合,以便它们与父节点分离。例如Include
:
var b = db.Blogs.Include(b => b.Posts).Include(b => b.Comments)
.Single(b => b.BlogId == 2);
db.Blogs.Remove(b);
db.SaveChanges();
或者Load
和其他答案一样。
另一种选择可能是使用Entity Framework Extented。它的一个功能是批量更新,它允许在IQueryable
给出模板记录的一次性更新记录。这看起来像这样:
using EntityFramework.Extensions;
...
db.Posts.Where(p => p.BlogId == 2)
.Update(p => new Post { BlogId = default(int?) });
db.Blogs.Remove(b);
db.SaveChanges();
仅修改模板记录中设置的属性。要进行此事务,您应该将所有语句包装在TransactionScope
。