Answered by:
mapping collections of components with code first and the fluent API

Question
-
Hello guys.
I've just started looking at EF code first approach and I've got a couple of questions. I've got the following model (simplified and just typed, so think of it as pseudocode):
public class Entity{
//other properties removed
private IList<Contact> _contacts = new List<Contact>();
public IEnumerable<Contract> Contacts{
get{ return new ReadOnlyCollection(_contacts); }
private set{_contacts = new List<Contact>(value);}
}
public void AddContact( Contact ct){
//checking logic removed
_contacts.Add(ct);
}
}//simplified class (in real world, properties are readonly,
//there's a constructor which receives all the properties
//and there's some more logic for ensuring equality and hashcode generation)
public class Contact{
public String Value{get;set;}
public ContactKind ContactKind{get;set;}
}public enum ContactKind{
Phone,
Email
}In NH, I'm able to say that each entity has a collection of contact components. In practice, the mapping ends up adding a foreign key to the Contact table and it will always delete and insert all the contacts during an entity update operation. Notice that this means that I don't need to change my domain and the contact class remains ignorant about its database persistence.
Is there a way to do this kind of thing in EF (with the code first approach)? All the examples I've seen treat the classes as entities and, in practice, that means adding an entity property to Contact that references the associated entity (or adding an int property which has the id of the associated entity)...
thanks.
Luis AbreuTuesday, May 10, 2011 10:20 AM
Answers
-
Hello Luis,
your finding is correct. Primary key is necessary - there is no way to avoid this with code-first. In model first / database first (EDMX) entity without primary key are possible but it makes them readonly. There are even more problems with your code. EF code first needs access to the navigation property to be able to populate it - it means that you cannot hide contacts in the Entity. Last problem is that EF doesn't support enums.
Best regards,
LadislavTuesday, May 10, 2011 9:00 PM
All replies
-
Hello Luis,
your finding is correct. Primary key is necessary - there is no way to avoid this with code-first. In model first / database first (EDMX) entity without primary key are possible but it makes them readonly. There are even more problems with your code. EF code first needs access to the navigation property to be able to populate it - it means that you cannot hide contacts in the Entity. Last problem is that EF doesn't support enums.
Best regards,
LadislavTuesday, May 10, 2011 9:00 PM -
Hello Ladislav.
Thanks for the feedback.
Yes, i've noticed those problems too...unfortunately, it seems like EF is still not quite ready for real world domain modelling. It's a lot better than it was when v1.0 come out, but these kind of small problems make it difficult to use for DDD scenarios...
Luis AbreuWednesday, May 11, 2011 8:33 AM