In a situation where you have a parent class which has one child class, what is the best pattern for mapping the entities.
I have seen a lot of suggestions where the parent has a reference to both the child class, and the child class id. E.g.
public class Parent
{
public int Id
{
get;
set;
}
public int ChildId
{
get;
set;
}
public virtual Child Child
{
get;
set;
}
}
public class Child
{
public int Id
{
get;
set;
}
}
public class ParentMapping : EntityTypeConfiguration<Parent>
{
public ParentMapping()
{
HasKey(x => x.Id);
HasRequired(X => x.Child)
.WithMany()
.Map(x => x.ToTable("Parent")
.MapKey("ChildId"));
}
}
With this pattern, when saving the parent, if you want to swap out the child for a different but existing child, examples I have seen just update the ChildId and not the Child which feels wrong because the object is out of sync with itself.
The code looks neater without the ChildId but with this pattern I am having trouble saving the parent using an existing child because EF is trying to save a new child.
public class Parent
{
public int Id
{
get;
set;
}
public virtual Child Child
{
get;
set;
}
}
开发者_高级运维
What is the best pattern, I would like to know if the ChildId is needed, then how is the Child property kept in sync and will it be lazy loaded from the database or not.
This is difference between foreign key and independent association. When using foreign key association you can really use just key without loading the related object. It makes the reference out of sync if you have it loaded - which is not always the case. If you want to keep the reference in sync you are almost back in the situation which you must solve with independent association.
If you expose foreign key you should use it because it makes a lot of things much more easier. If you use the independent association you should do something like:
var parent = GetUpdatedParentSomehow();
// Dummy object for the old child if the relation is not loaded
parent.Child = new Child { Id = oldChildId };
// Attach the parent
context.Parents.Attach(parent);
// Create dummy for new child (you can also load a child from DB)
var child = new Child { ID = newChildId };
// No attach the child to the context so the context
// doesn't track it as a new child
context.Childs.Attach(child);
// Set a new child
parent.Child = child;
// Set parent as modified
context.Entry(parent).State = EntityState.Modified;
context.SaveChanges();
There is very strange part where I'm creating dummy for the old child. I'm almost sure that if I don't do it before attaching the parent and setting the new child I will get some exception during saving changes (in case of independent association).
精彩评论