Entity framework 在使用POCO时,我是否应该保持外键与引用同步
我看到很多关于在POCO中首先使用EF代码的示例,它们显示了如下内容:Entity framework 在使用POCO时,我是否应该保持外键与引用同步,entity-framework,entity-framework-4.1,ef-code-first,entity-framework-5,Entity Framework,Entity Framework 4.1,Ef Code First,Entity Framework 5,我看到很多关于在POCO中首先使用EF代码的示例,它们显示了如下内容: public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogId { get; set; } public virtual Blog Blog { get; set; }
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
现在,看看博客
属性。不应该是这样吗?
private Blog blog;
public virtual Blog Blog
{
get
{
return blog;
}
set
{
blog = value;
if (blog != null)
{
BlogId = blog.BlogId;
}
}
}
我的意思是,既然你已经用外键“污染”了你的模型,你不应该至少让它和引用保持同步吗?或者,在读取数据时,您不应该依赖于BlogId
(例如,您想知道特定的BlogId
是否在列表中)。或者,DbContext
上有一个神奇的属性(比如KeepForeingKeysPropertiesSyncronizedWithReferences
)对我来说就是这样,而我是唯一一个担心这一点的悲伤程序员?还是我偏执?(还有,很抱歉我的英语不好)
编辑
对不起,这真是个愚蠢的问题。Stefan是对的,EF真的为你做了这件事。我没有看到这一点,因为我传递的引用加载了
AsNoTracking()
。只有在这种情况下,您才会有一个ID为的引用,并且foring键字段将为0。只要您传递的引用已经在上下文中,它就会起作用。您本身不需要这样做,EF会为您这样做。如果设置独立关联属性,EF将同步外键属性以反映您的更改,反之亦然。提醒您,这不会立即自动发生,我想这是在调用SaveChanges后发生的,但我不确定。
如果你想知道为什么有些人会使用外键属性:它在独立应用程序(如web应用程序)中更方便。当您需要扩展应用程序时,它还可以帮助提高性能(请在最近的某个MS博客文章中阅读此内容)。
基本上,你只需要自己做这件事,如果你是混合和匹配;在一种方法中使用独立关联属性,在另一种方法中使用外键属性。首先生成数据库代码 您似乎选择了“是”,否则将收到以下错误 发生引用完整性约束冲突:属性 定义引用约束的值不一致 在关系中的主体对象和从属对象之间 原则是你的文章对象,依赖是博客对象 当您尝试将未分配的上下文无关POCO附加回上下文时 EF 4.1数据库上下文:
using (TransactionScope scope = new TransactionScope())
using (ITAMdbContext db = new ITAMdbContext())
{
db.Entry(post).State = System.Data.EntityState.Unchanged; // error here
db.Entry(post).State = System.Data.EntityState.Modified;
db.SaveChnages();
此错误由..解决
using (TransactionScope scope = new TransactionScope())
using (ITAMdbContext db = new ITAMdbContext())
{
post.BlogId = post.Blog.BlogId;
// fix the broken FK value, EF will not do this for
// you, it does not know if post.BlogId or the post.Blog.BlogId should be chosen.
db.Entry(post).State = System.Data.EntityState.Unchanged;
db.Entry(post).State = System.Data.EntityState.Modified;
db.SaveChnages();
如果您的POCO对象不是自动生成的,那么您的方式是有效的
将post设置为“未更改”,然后将其设置为“已修改”的原因是,在对象上设置的第一个条目()。将相同的状态级联到所有子对象!很可怕,但这就是它的工作方式。
然后,当您再次调用它时,它只会修改post对象。这将停止修改或添加子对象
编辑:这不再是必需的,它已经为你完成了我不知道EF,但是如果你使用了NHibernate,你就根本不会在BlogId属性中添加它。我认为使用BlogId的可能性很好,所以我不需要有博客引用,仍然可以保存关联。我只是对保持同步感到困惑——对我来说,这似乎是显而易见的事情,但我从未见过有人这样做,所以也许我错了:/