3

伙计们,

我在创建具有 master 的新对象时遇到问题。问题实际上是 EF 也在尝试创建主对象,但我不需要它。

我的两个 poco 课程如下所示:

[DataContract(IsReference = true)]
public class Application
{
    [DataMember]
    public int ID { get; set; }

    [DataMemeber]
    public int ProjectManagerId {get; set; }

    [DataMember]
    public ProjectManager PM { get; set;}
}

[DataContract(IsReference = true)]
public class ProjectManager
{
    [DataMember]
    public int ID { get; set; }

    [DataMember]
    public string FullName { get; set; }

}

当我在 ASP.NET MVC 页面上创建新对象时,我有一个Application类对象,它的 ProjectManagerId 等于 1,PM 字段的 ID = 0 和 FullName,例如“Forest Gump”。

所以,当我添加对象时,我有异常 application.PM.ID 不能为 0:

context.Applications.AddObject(application); 
context.SaveChanges();

是否可以在不添加主对象的情况下添加对象我的对象?

我找到了解决方法,但我不喜欢它:它在将对象添加到上下文之前将 PM 字段分配给 null

application.PM = null;
4

1 回答 1

4

EF 有一个您必须了解的核心规则。它适用于整个对象图,并且不允许在同一个对象图中组合分离和附加的实体。这意味着AttachandAddObject方法将始终在对象图中的所有实体上执行(它将遍历您的导航属性并递归执行操作)。

由于这种基本行为,您必须手动处理现有对象。你有三个选择:

不要使用导航属性。你的Application班级ProjectManagerId暴露了。您只需将此属性设置ID为现有管理器的属性,而无需填充ProjectManager导航属性来构建关系。

var application = new Application { ProjectManagerId = 1 };
context.Applications.AddObject(application);
context.SaveChanges();

附加您的父母,添加孩子,然后才在他们之间建立联系:

// Create attached existing project manager
var projectManager = new ProjectManager { ID = 1 };
context.ProjectManagers.Attach(projectManager);

// Create a new added application
var application = new Applications();
context.Applications.AddObject(application);

// Now you are making relation between two entities tracked by the context
application.ProjectManager = projectManager;  
context.SaveChanges();

最后一个选项是简单地修复现有实体的状态。在这种情况下,您将设置项目管理器保持不变,而应用程序仍将保持在添加状态:

// Add application and its related project manager
context.Applications.AddObject(application);
context.ObjectStateManager.ChangeObjectState(application.ProjectManager, EntityState.Unchanged);
context.SaveChanges();
于 2013-02-08T09:09:04.777 回答