EF 6 可选 FK ,删除仍然报错
EF 6 optional FK , delete still produces error
所以我有这两个简单的模型
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 违规 error.Notice FK blog_id 可以为空,所以我认为 EF 会处理删除,并使相应的 FK 为空。
你能告诉我我错过了什么吗?
必须为 EF 加载实体才能处理将其外键设置为 null。
var b = db.Blogs.Find(2);
db.Entry(b).Collection(b => b.Posts).Load();
db.Blogs.Remove(b);
db.SaveChanges();
请记住,Entity Framework 只能更新它已加载的实体。
当然有一些方法可以通过原始 SQL 语句更新数据库记录,您也可以通过 EF 执行这些语句,但这不是作为 ORM 的 EF 的核心。
所以如果你只想使用 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
.
中
所以我有这两个简单的模型
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 违规 error.Notice FK blog_id 可以为空,所以我认为 EF 会处理删除,并使相应的 FK 为空。 你能告诉我我错过了什么吗?
必须为 EF 加载实体才能处理将其外键设置为 null。
var b = db.Blogs.Find(2);
db.Entry(b).Collection(b => b.Posts).Load();
db.Blogs.Remove(b);
db.SaveChanges();
请记住,Entity Framework 只能更新它已加载的实体。
当然有一些方法可以通过原始 SQL 语句更新数据库记录,您也可以通过 EF 执行这些语句,但这不是作为 ORM 的 EF 的核心。
所以如果你只想使用 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
.