EF 6可选FK,删除仍然会产生错误

时间:2015-05-23 01:22:41

标签: entity-framework foreign-key-relationship sql-delete

所以我有这两个简单的模型

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。 你能告诉我我错过了什么吗?

2 个答案:

答案 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