实体框架:context.AddObject,无需添加母版

时间:2013-02-08 08:00:23

标签: entity-framework

人,

当我创建具有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();

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

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

application.PM = null;

1 个答案:

答案 0 :(得分:4)

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

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

不要使用导航属性。您的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();