使用POCO时,我应该将外键与引用同步吗?

时间:2012-08-30 07:09:34

标签: entity-framework entity-framework-4.1 ef-code-first entity-framework-5

我看到很多关于首先使用EF代码的示例,其中POCO显示如下:

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; }
}

现在,查看Blog属性。不应该是这样的:

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的引用,而foreing key字段将为0.只要你传递一个已经在上下文中的引用,它就应该有效。

2 个答案:

答案 0 :(得分:1)

你不需要这样做,EF会为你做这件事 如果设置了独立关联属性,EF将同步外键属性以反映您的更改,反之亦然。它不会立即自动提醒您,我认为这是在调用SaveChanges后发生但我不确定 如果你想知道为什么有些人使用外键属性:它在web应用等分离的应用程序中更方便。当您需要扩展应用程序时,它还可以帮助提高性能(请在最近的某篇MS博客文章中阅读) 基本上,如果你正在混合和匹配,你只需要自己做;当你在一个方法中使用独立关联属性而在另一个方法中你正在使用外键属性时。

答案 1 :(得分:0)

生成数据库第一个代码。

看来你没有,否则你会收到以下错误。

  

发生了参照完整性约束违规:属性   定义引用约束的值不一致   在关系中的主要和依赖对象之间。

原则是你的Post对象,依赖于Blog对象。

当您尝试将未分配的上下文自由POCO附加回上下文时 EF 4.1 DBContext:

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设置为Unchanged然后将其设置为Modified的原因是因为对象上的第一个Entry()。State设置会将相同的状态级联到所有子对象!可怕,但这就是它的工作方式。 然后当你再次调用它时它只修改post对象。这会停止修改或添加子对象。

编辑:这不再是必需的,它是为你完成的