Reputation: 353
folks,
I have a problem when I'm creating new object that has master. The problem actually is that EF is trying to create master object too, but I don't need it.
My two poco classes look like:
[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; }
}
When I'm creating new object on ASP.NET MVC page, I've got object of Application
class, that has ProjectManagerId equals to 1 and PM field with ID = 0 and FullName for example 'Forest Gump'.
So, when I'm adding object, I have exception that application.PM.ID cannot be 0:
context.Applications.AddObject(application);
context.SaveChanges();
Is it possible to addobject my object without adding master?
I found workaround, but I don't like it: it is assigning PM field to null before adding object to context
application.PM = null;
Upvotes: 3
Views: 885
Reputation: 364369
EF has one core rule you must be aware of. It works with whole object graph and it doesn't allow combining detached and attached entities in the same object graph. It means that both Attach
and AddObject
method will be always executed on all entities in the object graph (it will traverse your navigation properties and execute the operation recursively).
Because of this essential behavior you must handle existing objects manually. You have three options:
Don't use navigation property. Your Application
class has ProjectManagerId
exposed. You need only to set this property to ID
of the existing manger without populating ProjectManager
navigation property to build a relation.
var application = new Application { ProjectManagerId = 1 };
context.Applications.AddObject(application);
context.SaveChanges();
Attach your parent, add child and only after that make connection between them:
// 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();
The last option is simply fixing the state of existing entities. In this case you will set project manger to be unchanged while application will still remain in the added state:
// Add application and its related project manager
context.Applications.AddObject(application);
context.ObjectStateManager.ChangeObjectState(application.ProjectManager, EntityState.Unchanged);
context.SaveChanges();
Upvotes: 4