MSD has reposted this discussion as a new topic, Collection of subclass, http://groups.google.com/group/nhusers/browse_thread/thread/b922f97a88229687#.
You may want to follow FM's comments on his implementation. Jide On Aug 16, 9:46 am, "Frans Bouma" <[email protected]> wrote: > > I went with this: > > why the flood of FK fields? It now is technically possible that a > contactinfo instance is shared among employee and customer, IMHO not what > you want. > > FB > > > > > > > > > Table > > > ContactInfo > > id > > ContactValue > > ContactType > > Employee_ID_FK > > Customer_ID_FK > > ANY_CONTACT_USER_FK > > etc > > . > > . > > . > > > Class > > public class Contact > > { > > public virtual string ContactValue { get; set; } > > public virtual short ContactType { get; set; } } > > > Here is dummy table that uses contact info: > > DummyContactUser( > > ID > > Name > > ) > > and the class: > > > public class DummyContactUser > > { > > public int ID { get; private set; } > > public string Name { get; set; } > > public ISet<Contact> ContactInfo { get; set; } > > public DummyContactUser() > > { > > ContactInfo = new HashedSet<Contact>(); > > } > > } > > > and a mapping like this: > > > public class DummyContactUserMap : ClassMap<DummyContactUser> > > { > > public DummyContactUserMap() > > { > > Not.LazyLoad(); > > Id(x => x.ID); > > Map(x => x.Name); > > > HasMany(x => x.ContactInfo) > > .Component(x => > > { > > > x.Map(y => y.ContactValue); > > x.Map(y => y.ContactType); > > }) > > .Not.LazyLoad() > > .Table("ContactInfo") > > .KeyColumn("ANY_CONTACT_USER_FK"); > > } > > } > > > So as you can see I implemented it as a set of Components where I am using > > the foreign key as the key column and I would do that kind of mapping for > > every class that needs ContactInfo by changing the FK I use for each. > > > Does this make sense? Any pitfalls I might have missed? > > Thanks. > > > On Sun, Aug 15, 2010 at 3:24 PM, JideO <[email protected]> wrote: > > > You could use > > > ContactInfo > > Id > > ContactValue > > ContactType > > ... > > Employee > > EmpId > > StaffNo > > ... > > EmployeeContactInfo > > EmpId > > ContactInfoId > > ... > > Person > > PersonId > > FirstName > > ... > > PersonContactInfo > > PersonId > > ContactInfoId > > ... > > > etc etc. You'd have one EntityContactInfo table for each Entity that > > needs to use the ContactInfo. The relationship between > > EntityContactInfo and ContactInfo can simply be unidirectional but > > i'm > > sure it can be done bidirectionally with some inheritance. > > > A warning, as FB has noted earlier, this comes with the > > responsibility > > of managing the additional complexity that comes with what this > > multiple unlimited address thing. If you have no other choice...but > > sometimes reexamining what you're trying to achieve may help you > > simplify it a little. > > > Jide > > > On Aug 15, 12:45 pm, "Frans Bouma" <[email protected]> wrote: > > > > Thanks Frans for the explanation but if you could bear with me a > > bit more: > > > > I understand the idea of using a component that has the actual > > columns in > > > > the parent table instead of a separate table. But as far as I > > know this > > > > works if the component is a single instance and not a > collection: > > > > Person.SingleContactInfo > > > > Not Person.ListOfContactInfo > > > > because a list of contactInfo would not be of a predetermined > > size, so how > > > > would the columns be on the database side (how many columns to > > represent > > > the > > > > contactInfo?) > > > > that's indeed a problem with using components in this > case: > > a > > > flexible list of contact infos, which can be extended till > whatever > > size is > > > indeed requiring that you model it outside the entity. I refered > to > > > 'phonenumber' as a metaphore in my previous email as you often see > > this > > > happening with phonenumber as well: "we need different types of > > > phonenumbers: mobile, landline, work, home, second, third. etc..", > > which > > > could indeed be done by creating an entity out of it (so keep > > ContactInfo as > > > a separate entity), but it's also a sign you might want to take a > > step back > > > and think about if you need the list of contact info's, as it > comes > > with a > > > price: you need extra logic, as I described. > > > > Say you want to stick with the list thing, and really want > > it that > > > way, you can keep the ContactInfo table, and solve it in two ways: > > > > 1) Keep it but it's only for Employee. Add an FK to Employee in > the > > > ContactInfo table and rename the table to EmployeeContactInfo. > This > > is > > > straight forward. > > > 2) Create a ContactGroup table, which contains 1 field: ID* and in > > the > > > tables which have to have a list of contacts, add an FK field to > > > ContactGroup. In ContactInfo, add an FK to ContactGroup. So > > EMployee '5' has > > > as ContactGroupId (the fk to ContactGroup) the value '3', and in > > ContactInfo > > > there are 1 or more rows with the FK field ContactGroupId set to > 3. > > To > > > obtain the contacts for Employee, you thus join with Contactgroup > > and > > > ContactInfo. > > > > FB > > > > > Thanks > > > > > On Sun, Aug 15, 2010 at 1:44 PM, Frans Bouma <[email protected]> > wrote: > > > > > > The main problem is that ContactInfo is not used by only > the > > > > Employee > > > > > Entity, that is why I am not sure how to design it on the > > database > > > > side. > > > > > You mix type with instance. If you define a > ContactInfo > > > > component > > > > (Valuetype in DDD), it's a type. You can re-use that in > > multiple > > > > entities. > > > > It just doesn't have its own table, as it's not a separate > > entity > > > > (you can't > > > > save it separately and fetch it separately, as it doesn't > make > > > sense, > > > > it > > > > only makes sense in the context of its containing entity) > > > > > > Also, specifiying JUST 3 Contact Infos for the Employee > does > > not > > > > work > > > > since > > > > > the user must be able to add and remove from the contact > > info as a > > > > list. > > > > > Same goes for Address table, it is used by more than one > > entity > > > and > > > > probably > > > > > by the same entity more than once. > > > > > Instance or type re-use? I was talking about instance > > re-use. > > > > In > > > > almost all applications which request an 'address' to be > > filled in, > > > > you > > > > can't select one from a list, you just fill in the fields, > > like with > > > > name, > > > > day of birth etc. So the fields making up the 'address' are > > simply > > > > part of > > > > the entity they belong to, you won't share an address > instance > > (i.e. > > > > the > > > > data!) with another entity by letting that OTHER entity > > reference > > > the > > > > same > > > > row, but you will do that with a real entity, like Customer. > > > > > Address, and also contact info, phone numbers (same > > thing), > > > > are 'on > > > > the edge' of being seen as entity or valuetype, as you can > add > > an > > > > 'id' and > > > > it looks like an entity. But you've to think about how it > > behaves in > > > > the > > > > domain model: what is its purpose: if its purpose is to group > > fields > > > > inside > > > > an entity, you shouldn't create it as an entity, but as a > > component > > > > (valuetype). > > > > > Your UI reference that the user should add/remove it > > from a > > > > list is > > > > typical for the point of view where address, contact info, > > > > phonenumber etc. > > > > are seen as real entities, but a question was asked how to > > model it, > > > > and I > > > > think it's wiser to look into why you'd really want to define > > it as > > > > an > > > > entity. For example, your list idea in the UI, requires extra > > logic, > > > > like do > > > > I allow 10 contact info's all of the same type for an > > employee? Does > > > > it have > > > > to have contact info of at least 3 different types? > > > > > FB > > > > > > On Sun, Aug 15, 2010 at 12:33 PM, Frans Bouma <[email protected]> > > wrote: > > > > > > > I have a ContactInfo Table : > > > > > > ContactInfo( > > > > > > ID int IDENTITY(1,1) NOT NULL, --PK > > > > > > ContactValue varchar(100) NOT NULL, > > > > > > ContactType smallint] NOT NULL > > > > > > ) > > > > > > In my model multiple entities/tables would need to > > have a > > > > list of > > > > > > ContactInfo entries. > > > > > > Example: > > > > > > > Employee has 3 contact infos: 1 email and 2 phone > > numbers. > > > > I would > > > > > then > > > > > have > > > > > > a ContactInfo with ContactType = 2(email), and 2 > > > > ContactInfo with > > > > > Type = > > > > > > 1(phone). > > > > > > ContactInfo isn't an entity. An entity is a > > group of > > > > > attributes > > > > > (fields) with its own identity. Your contact info > > isn't > > > that, > > > > it's 1 > > > > > value. > > > > > > So I'd model it as a Component, and define 3 > > contact > > > > infos in > > > > > Employee. This is less flexible (you can't add more > > without > > > > modifying > > > > > employee), however it's IMHO better, because you're > > not > > > going > > > > to re- > > > > > use > > > > > contactinfo. It's the same as address. A lot of > people > > model > > > > that as > > > > > a > > > > > separate entity, which is in most cases not really > > > > beneficial, as > > > > you > > > > > don't > > > > > re-use entity instances (rows in the table) > > > > > > FB > > > > > > > Now the question is how to link this Entity to the > > > > different > > > > users? > > > > > It > > > > > looks > > > > > > like inheritance with only a difference in foreign > > keys. > > > > Does > > > > > adding an FK > > > > > > to every user Table make > > ... > > read more »- Hide quoted text - > > - Show quoted text - -- You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
