使用相关对象EF 3.5保存对象时出现异常

时间:2011-06-04 20:21:23

标签: entity-framework

我收到一条错误,告诉我:“EntityKey属性只能在属性的当前值为null时设置。”当我尝试用相关对象保存对象时。 这是我的代码:

public partial class Cat{
    public bool Save()
    {
        try
        {
            using (var context = new PhonebookEntities())
            {
                if (this.ParentCat != null)
                {
                    if (this.ParentCat.CategoryID == 0)
                        context.AddToCats(this.ParentCat);
                }
                context.AddToCats(this);
                context.SaveChanges();
            }
            return true;
        }
        catch (System.Exception)
        {
            return false;
        }
}

在这里,我创建一个Cat对象并将其连接到一个关联的父Cat对象,然后调用save方法:

        var cat = new Cat()
        {
            CatName = "Test",
            ParentCat = Cat.GetById(1)
        };
        cat.Save();

1 个答案:

答案 0 :(得分:1)

让我猜一下 - Cat.GetById(1)看起来像:

public static Cat GetById(int id)
{
     using (var context = new PhonebookEntities())
     {
          return context.Cats.Single(c => c.Id == id);
     }
}

您正在使用两种不同的上下文 - 这是问题的根源。第一个上下文加载Cat并填充它EntityKey,但第二个上下文不知道此实例,因此一旦您调用AddToCats,它将同时添加新的CatParentCat好但是它失败了,因为新实体不能填充EntityKey(我知道它不是一个新实体,而是它的上下文的新实例!)。

基于

Add的操作始终在对象图中添加所有未知实体。只有当相同的上下文加载实体或者为该实体调用.Attach时,才能通过上下文知道实体。

因此,这也是错误的:

if (this.ParentCat != null)
{
     if (this.ParentCat.CategoryID == 0)
         context.AddToCats(this.ParentCat);
}

未知ParentCat将与当前Cat一起自动添加。如果您拨打此电话,它也会添加当前Cat,但下一个电话会尝试再次添加=>你可能会遇到例外。

这整体可以通过两种方式解决:

  • 在保存ParentCat
  • 的同一上下文实例上加载Cat
  • 请勿加载ParentCat并使用虚拟课程或尝试设置EntityKey

虚拟课程方法:

var parentCat = new Cat() { Id = 1 };
context.Cats.Attach(parentCat); // Use correct entity set name
var cat = new Cat()
{
    CatName = "Test",
    ParentCat = parentCat
};
cat.Save();

EntityKey aproach(这更像是猜测):

var cat = new Cat()
{
    CatName = "Test",
    // I hope ParentCatReference will be initialized
    ParentCatReference.EntityKey = new EntityKey("Cats", "Id", 1) // Use correct entity set name
};
cat.Save();