6

我看到很多关于首先使用 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(like KeepForeingKeysPropertiesSyncronizedWithReferences) 上有一个神奇的属性对我这样做,而我是唯一对此感到担忧的可悲程序员?还是我偏执?(另外,对不起我的英语不好)

编辑 对不起-这确实是一个愚蠢的问题。Stefan 是对的,EF 确实为您做到了这一点。我没有看到这个,因为我传递的引用加载了AsNoTracking(). 只有在这种情况下,您才会有一个带有 ID 的引用,并且外键字段将为 0。只要您传递一个已经在上下文中的引用,它应该可以工作。

4

2 回答 2

1

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

于 2012-08-30T10:49:20.390 回答
0

生成数据库优先代码。

看来您是这样做的,否则您将收到以下错误。

发生参照完整性约束冲突:定义参照约束的属性值在关系中的主体对象和从属对象之间不一致。

Principle 是您的 Post 对象,dependent 是 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 对象。这会阻止修改或添加子对象。

编辑:这不再需要,它为你完成

于 2013-04-25T13:53:43.533 回答