ContactInfor Table, how would you design it

4 views
Skip to first unread message

MSD

unread,
Aug 14, 2010, 6:04:00 PM8/14/10
to nhusers
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).

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 sense / good design?

Also, how do we represent such a thing in the domain model? Do we
create duplicate classes for every use? EmployeeContactInfo,
ClientContactInfo, etc... How do we map those?

I know those are a lot of questions but I think the idea is clear
enough, thanks for the help in advance.

Frans Bouma

unread,
Aug 15, 2010, 5:33:05 AM8/15/10
to nhu...@googlegroups.com
> 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 sense / good design?
>
> Also, how do we represent such a thing in the domain model? Do we create
> duplicate classes for every use? EmployeeContactInfo, ClientContactInfo,
> etc... How do we map those?
>
> I know those are a lot of questions but I think the idea is clear enough,
> thanks for the help in advance.
>

> --
> You received this message because you are subscribed to the Google Groups
> "nhusers" group.
> To post to this group, send email to nhu...@googlegroups.com.
> To unsubscribe from this group, send email to
> nhusers+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/nhusers?hl=en.

Muhammad Shehabeddeen

unread,
Aug 15, 2010, 6:08:01 AM8/15/10
to nhu...@googlegroups.com
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. 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.

Frans Bouma

unread,
Aug 15, 2010, 6:44:52 AM8/15/10
to nhu...@googlegroups.com
> 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

> <mailto:nhusers%2Bunsu...@googlegroups.com> .


> > 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 nhu...@googlegroups.com.
> To unsubscribe from this group, send email to
> nhusers+u...@googlegroups.com

> <mailto:nhusers%2Bunsu...@googlegroups.com> .

Muhammad Shehabeddeen

unread,
Aug 15, 2010, 7:16:23 AM8/15/10
to nhu...@googlegroups.com
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?)

Thanks

Frans Bouma

unread,
Aug 15, 2010, 7:45:17 AM8/15/10
to nhu...@googlegroups.com
> 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

> > <mailto:nhusers%2Bunsu...@googlegroups.com
> <mailto:nhusers%252Buns...@googlegroups.com> > .


>
> > > 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
> nhu...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > nhusers+u...@googlegroups.com
> <mailto:nhusers%2Bunsu...@googlegroups.com>
>

> > <mailto:nhusers%2Bunsu...@googlegroups.com
> <mailto:nhusers%252Buns...@googlegroups.com> > .

JideO

unread,
Aug 15, 2010, 8:24:49 AM8/15/10
to nhusers
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
> >http://groups.google.com/group/nhusers?hl=en.- Hide quoted text -
>
> - Show quoted text -

Muhammad Shehabeddeen

unread,
Aug 15, 2010, 3:17:56 PM8/15/10
to nhu...@googlegroups.com
I went with this:

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.

Frans Bouma

unread,
Aug 16, 2010, 4:46:38 AM8/16/10
to nhu...@googlegroups.com
> 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

> > > > <mailto:nhusers%2Bunsu...@googlegroups.com
> <mailto:nhusers%252Buns...@googlegroups.com>
> > > <mailto:nhusers%252Buns...@googlegroups.com
> <mailto:nhusers%25252Bun...@googlegroups.com> > > .


> >
> > > > > 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
> > > nhu...@googlegroups.com.
> > > > To unsubscribe from this group, send email to
> > > > nhusers+u...@googlegroups.com
> <mailto:nhusers%2Bunsu...@googlegroups.com>
> > > <mailto:nhusers%2Bunsu...@googlegroups.com
> <mailto:nhusers%252Buns...@googlegroups.com> >
> >

> > > > <mailto:nhusers%2Bunsu...@googlegroups.com
> <mailto:nhusers%252Buns...@googlegroups.com>
> > > <mailto:nhusers%252Buns...@googlegroups.com
> <mailto:nhusers%25252Bun...@googlegroups.com> > > .

JideO

unread,
Aug 16, 2010, 3:06:47 PM8/16/10
to nhusers
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
> ...
>
> read more »- Hide quoted text -

Fabio Maulo

unread,
Aug 16, 2010, 11:54:06 PM8/16/10
to nhu...@googlegroups.com

Frans Bouma

unread,
Aug 17, 2010, 3:06:59 AM8/17/10
to nhu...@googlegroups.com
> <any>
> http://nhforge.org/doc/nh/en/index.html#mapping-types-anymapping

that would require him giving up FK constraints for referential
integrity. IMHO something you'd never want to.

FB

> <mailto:nhusers%25252Bun...@googlegroups.com> > > .


> >
> > > > > 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
> > > nhu...@googlegroups.com.
> > > > To unsubscribe from this group, send email to
> > > > nhusers+u...@googlegroups.com
> <mailto:nhusers%2Bunsu...@googlegroups.com>
> > > <mailto:nhusers%2Bunsu...@googlegroups.com
> <mailto:nhusers%252Buns...@googlegroups.com> >
> >

> <mailto:nhusers%25252Bun...@googlegroups.com> > > .

> > >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
nhu...@googlegroups.com.
> To unsubscribe from this group, send email to

> nhusers+u...@googlegroups.com
> <mailto:nhusers%2Bunsu...@googlegroups.com> .
> 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 nhu...@googlegroups.com.
> To unsubscribe from this group, send email to
> nhusers+u...@googlegroups.com
> <mailto:nhusers%2Bunsu...@googlegroups.com> .
> For more options, visit this group at
> http://groups.google.com/group/nhusers?hl=en.
>
>
>
>
>
> --

> Fabio Maulo

Fabio Maulo

unread,
Aug 17, 2010, 9:06:26 AM8/17/10
to nhu...@googlegroups.com
ok
--
Fabio Maulo

Reply all
Reply to author
Forward
0 new messages