Hey Jide, You could also use a > contained reference where the EntityContactInfo would have a reference > to the ContactInfo which would actually have avoided the problem you > ran into because you would have a separate mapping and table for each > EntityContactInfo >
> The above approach is virtually the same as using table-per-concrete- > class inheritance mapping which may actually be better. Table per concrete class mapping means 1 table and 1 mapping for EmployeeContactInfo and 1 table and 1 mapping for StudentContactInfo, no table nor mapping for the base class ContactInfo. When you "would have a reference to the ContactInfo", do you mean that the subclasses EmployeeContactInfo and StudentContactInfo would have a property MyBaseContactInfo? I don't get it. If on the other hand you mean by "reference" a foreign key, this has no place in a table per concrete class mapping since there is no table for the base class. The containment approach avoids this mixup and allows you to extend > both ways. I am still here assuming I understand what you mean by the "containment approach" as the "table per concrete class" approach. How would that solve the mixup? In that approach there would still be both EntityType and a ValueType columns. Concerning which approach I am going for, I am more inclined to use a table per class hierarchy strategy, since I feel it is less of a fuss to add FKs to a table than add tables; but I am going to give it a bit more thought and compare the different options I have received. I really appreciate it, thanks. Regards, On Tue, Aug 17, 2010 at 1:55 AM, JideO <[email protected]> wrote: > I did not go beyond mentioning inheritance because I did not want to > influence your eventual implementation of the solution which I > suggested i.e. have a separate EntityContactInfo for each Entity that > uses the ContactInfo. > > Inheritance is one of the ways to implement it. You could also use a > contained reference where the EntityContactInfo would have a reference > to the ContactInfo which would actually have avoided the problem you > ran into because you would have a separate mapping and table for each > EntityContactInfo. I initially thought there would be problems with a > bidirectional association with this approach but I'm not sure about > that anymore. However I still don't like that for each new > EntityContactInfo you have to touch the ContactInfo mapping to add the > new EntityContactInfo reverse mapping. > > The above approach is virtually the same as using table-per-concrete- > class inheritance mapping which may actually be better. > > The approach you tried to implement is the table-per-hierarchy for > which you will need a separate column in the ContactInfo table for > each Entity that uses ContactInfo and not one EntityID for all > entities as you attempted to do. > ContactInfo > ID int > EntityType char(1) > EmployeeID > CustomerID > SupplierID > .... > ValueType smallint > Value nvarchar(50) > > You can also use the other table-per-class at the expense of more > joins and other additional issues. However the weakness with the > inheritance approach is that you are basically mixing two separate > inheritance hierarchies which you'll see in the above and your table > definition where you have both EntityType and a ValueType columns in > the table. This basically means you have given up the choice of > extending by inheritance the types of ContactInfos you will have i.e. > PostalContactInfo, EmailContactInfo, PhoneContactInfo etc. > > The containment approach avoids this mixup and allows you to extend > both ways. > > I hope I have been specific enough without unduly influencing your > implementation. I would also like to see how your approach because it > may provide new ideas. > > Jide > > > > On Aug 16, 8:27 pm, Muhammad Shehabeddeen > <[email protected]> wrote: > > I re-checked what you had posted, and I agree you kind of mentioned > > inheritance in your post, but you did not show the design for the tables > > which is the real CATCH here since I am using a single column as a shared > > FK. Please correct me if the coffee has not kicked in yet :) > > > > On Mon, Aug 16, 2010 at 10:23 PM, Muhammad Shehabeddeen < > > > > > > > > [email protected]> wrote: > > > Jide, > > > This implementation is different from the one in the other topic (it > uses > > > inheritance and a discriminator) and that is why I decided to post it > in a > > > separate question. This is one implementation suggested by a friend, > and I > > > was not asking how to implement the concept, I was just asking why the > > > implementation was flawed. In anyway, I can link to it if necessary. > > > > > On Mon, Aug 16, 2010 at 10:00 PM, JideO <[email protected]> wrote: > > > > >> MSD, > > > > >> You decided to repost the solution I suggested to you on the earlier > > >> topic: > > >>http://groups.google.com/group/nhusers/browse_thread/thread/1d2319f44. > .. > > >> as a different topic instead of continuing with the previous > > >> discussion. You will make it difficult other people including myself > > >> who were following the previous discussion to benefit from the > > >> contribution from the community on the topic. > > > > >> Apparently you have not properly implemented the mappings. > > > > >> Jide > > > > >> On Aug 16, 1:33 pm, Fabio Maulo <[email protected]> wrote: > > >> > various causes: > > >> > 1) your id (native) is unique in a class hierarchy (you have > Employee#1 > > >> and > > >> > Student#1) > > >> > 2) you are using the same column (EntityID) for both reference in a > > >> > table-per-class-hierarchy > > >> > 3) you are lucky; have a look to FKs created for EntityID column > > > > >> > Solution: > > >> > use two different column-name for the relation > > > > >> > On Mon, Aug 16, 2010 at 9:23 AM, MSD < > [email protected]> > > >> wrote: > > >> > > I have the following classes: > > >> > > public enum ContactValueType : short {...} > > >> > > public abstract class ContactDetail > > >> > > { > > >> > > public int ID { get; protected set; } > > >> > > public virtual ContactValueType ValueType { get; protected set; > } > > >> > > public virtual string Value { get; protected set; } > > > > >> > > public ContactDetail(){} > > >> > > public ContactDetail(ContactValueType valueType, string value) > > >> > > { > > >> > > this.ValueType = valueType; > > >> > > this.Value = value; > > >> > > } > > >> > > } > > >> > > public class StudentContactDetail : ContactDetail > > >> > > { > > >> > > public virtual Student Student { get; set; } > > >> > > public StudentContactDetail(){} > > >> > > public StudentContactDetail(Student student, ContactValueType > > >> > > valueType, string value) : base(valueType, value) > > >> > > { > > >> > > this.Student = student; > > >> > > } > > >> > > } > > >> > > public class EmployeeContactDetail : ContactDetail > > >> > > { > > >> > > public virtual Employee Employee { get; set; } > > >> > > public EmployeeContactDetail(){} > > >> > > public EmployeeContactDetail(Employee employee, > ContactValueType > > >> > > valueType, string value) : base(valueType, value) > > >> > > { > > >> > > this.Employee = employee; > > >> > > } > > >> > > } > > > > >> > > public class Employee > > >> > > { > > >> > > public int ID { get; protected set; } > > >> > > public virtual string Name { get; set; } > > >> > > public virtual > > >> > > Iesi.Collections.Generic.ISet<EmployeeContactDetail> > ContactDetails > > >> > > { get; protected set; } > > > > >> > > protected Employee() > > >> > > { > > >> > > ContactDetails = new > > >> > > Iesi.Collections.Generic.HashedSet<EmployeeContactDetail>(); > > >> > > } > > >> > > public Employee(string name) : this() > > >> > > { > > >> > > this.Name = name; > > >> > > } > > >> > > } > > > > >> > > public class Student > > >> > > { > > >> > > public int ID { get; protected set; } > > >> > > public virtual string Name { get; set; } > > >> > > public virtual > Iesi.Collections.Generic.ISet<StudentContactDetail> > > >> > > ContactDetails { get; protected set; } > > > > >> > > protected Student() > > >> > > { > > >> > > ContactDetails = new > > >> > > Iesi.Collections.Generic.HashedSet<StudentContactDetail>(); > > >> > > } > > >> > > public Student(string name): this() > > >> > > { > > >> > > this.Name = name; > > >> > > } > > >> > > } > > > > >> > > their tables: > > > > >> > > ContactDetail > > >> > > ID int > > >> > > EntityType char(1) > > >> > > EntityID int > > >> > > ValueType smallint > > >> > > Value nvarchar(50) > > >> > > Employee > > >> > > ID int > > >> > > Name nvarchar > > >> > > Student > > >> > > ID int > > >> > > Name nvarchar > > > > >> > > and their mappings: > > > > >> > > <class name="ContactDetail" table="ContactDetail" lazy="false"> > > >> > > <id name="ID" column="ID"> > > >> > > <generator class="native"/> > > >> > > </id> > > >> > > <discriminator column="EntityType" type="String" /> > > >> > > <property name="ValueType" column="ValueType"/> > > >> > > <property name="Value" column="Value"/> > > >> > > <subclass name="StudentContactDetail" discriminator-value="S"> > > >> > > <many-to-one name="Student"> > > >> > > <column name="EntityID" /> > > >> > > </many-to-one> > > >> > > </subclass> > > >> > > <subclass name="EmployeeContactDetail" discriminator-value="E"> > > >> > > <many-to-one name="Employee"> > > >> > > <column name="EntityID" /> > > >> > > </many-to-one> > > >> > > </subclass> > > >> > > </class> > > > > >> > > <class name="Student" table="Student" lazy="false"> > > >> > > <id name="ID"> > > >> > > <generator class="native"/> > > >> > > </id> > > >> > > <property name="Name"> > > >> > > <column name="Name" length="50" not-null="true" /> > > >> > > </property> > > >> > > <set name="ContactDetails" fetch="select" lazy="false" > > >> > > cascade="all"> > > >> > > <key column="EntityID" /> > > >> > > <one-to-many class="StudentContactDetail" /> > > >> > > </set> > > >> > > </class> > > > > >> > > <class name="Employee" table="Employee" lazy="false"> > > >> > > <id name="ID"> > > >> > > <generator class="native"/> > > >> > > </id> > > >> > > <property name="Name"> > > >> > > <column name="Name" length="50" not-null="true" /> > > >> > > </property> > > >> > > <set name="ContactDetails" fetch="select" lazy="false" > > >> > > cascade="all"> > > >> > > <key column="EntityID" /> > > >> > > <one-to-many class="EmployeeContactDetail" /> > > >> > > </set> > > >> > > </class> > > > > >> > > When persisting Student and Employee instances all is fine, but > when > > >> > > loading them, their ContactDetails collection is populated by ALL > > >> > > ContactDetails, that is disregarding the discriminator in the > select > > >> > > statement. > > >> > > Why is that and what can I do aside from this: > > > > >> > > <set name="ContactDetails" fetch="select" lazy="false" > cascade="all" > > >> > > where="EntityType='E'"> > > > > >> > > (adding the where attribute). > > >> > > Thanks > > > > >> > > -- > > >> > > 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]<nhusers%[email protected]> > <nhusers%[email protected]<nhusers%[email protected]> > > > > >> <nhusers%[email protected]<nhusers%[email protected]> > <nhusers%252bunsubscr...@googlegroups.com> > > >> > > > >> > > . > > >> > > For more options, visit this group at > > >> > >http://groups.google.com/group/nhusers?hl=en. > > > > >> > -- > > >> > Fabio Maulo- 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]<nhusers%[email protected]> > <nhusers%[email protected]<nhusers%[email protected]> > > > > >> . > > >> For more options, visit this group at > > >>http://groups.google.com/group/nhusers?hl=en.- 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]<nhusers%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/nhusers?hl=en. > > -- 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.
