1

I have two situations where I would want something like this. In my model, I have a Message which concerns either one or two Persons. Furthermore, the message has an association with two Addresses, i.e. a from Address and a to Address.

In the first situation with the two Persons, I would like to specify an association between Message and Person multiplicity of 1---1..2 or specify two associations, one with 1---1 and the other with 1---0..1. However, I cannot (or don't know how to) set the multiplicity to two. I can imagine that it might be possible to set it to 1--* with a constraint set to maximum 2 (however I don't know how to do that).
By adding the two associations I feel a bit weird when I look at the Message side because both associations have a 1 there which would indicate a Person should have two Messages related to it. I might want something like 0..1 on the Message side for both associations with an xor constraint on them or something, but I don't know if that is good practise or even possible in EF. I want to specify that it's max 2 Now it looks like a Person has two different Messages Now it looks like a Person can have two or no Messages

For the second situation, the problem is quite similar, except that there is always a from Address and always a to Address. Setting the multiplicity 1--* doesn't seem right to me. Here I would imagine there should definitely be two associations, a from and a to association (which happen to both go to the Address entity). This however results in the same problem on the Message side of having two 1's or two 0..1's.
Here the Address has two Messages Now the Address has zero to two Messages

So my question is, how do I model this correctly in an EDM?

Thanks in advance.

Update 1:

To clarify the question, I will give a little background information on why I need such a model. I have to be able to create a message. In this message I have to specify whether it concerns one or two persons. Of these persons I specify the first name, last name and some other non-unique properties (two people can have the same name). I could dump all these properties in the Message entity (fname1, lname1, fname2, lname2), but that seems a bad idea. Hence the Person entity was born. However, this might look like a Person can be linked to many messages, but this is not the case. There can be two different persons with the same properties. There is no way of telling whether these persons are actually the same person in real life or not.

In the case of the addresses, a similar argument holds. Two addresses can be spelled a bit differently, but if I write them on a letter and mail it, they will both arrive at the same location (e.g. sesamestreet or sesamestr.). So I don't have one Address entity connected to multiple Messages. Again, the only reason Address is a separate entity, is because I have two of em with exactly the same properties. Everything in message Message split up From a database design point of view this might not make sense, from a class diagram perspective it might make a bit more sense. I was under the impression that the EDM in EF should not be like a database design, but more like a domain model, so I hope I did the right thing.

Update 2:

I just thought of what I think might be the best way in this case. Because there is virtually no difference between Person1 and Person2 I feel like making the association between Message and Person 1..* acceptable. The fact that many means two will be something for lower layers to handle. In the address case, the from and to are quite different. They are both addresses, but I don't feel I can make em a list. I could split the from and to address into separate entities and let them inherit from Address. Then associate Message with each of the subclasses. It might seem a bit overkill, but you could reason that a from address might at some point have different requirements than a to address and hence different properties. The solution

I am not 100% happy though (especially with the address part). This solution might or might not be OK, but I feel like it avoids the core problem.

Matthijs Wessels
  • 6,530
  • 8
  • 60
  • 103

2 Answers2

0

For the first problem (Message - Person):

The crucial question is: do you want person1 to be non-nullable? And person2?

The second alternative you sketched looks pretty okay to me considered that you require a message to have exactly 1 Person1 (say: creator of the message), so a non nullable property. Person2 (say: person who last updated the message) can be either null or linked to an existing person. Fine!

What you see from the person class perspective is that it has two associations (and 2 navigation properties, which you collapsed...) one for thos messages where a specific person (instance of person entity) is the creator of and one for those messages where this specific person was the last updater. Pretty Fine! Isn't it? This way you can query the model from the perspective of the message (give me all messages and also the persons of each message that created it and last updated it...) Or...query a person and collect all messages that this person created or was the last updater of...get it?

But all comes down to determining if you allow nullability for Person1 and Person2.

I didn't read your second question, but think it's more of the same. need some advice with that one too? Just call me.

Furthermore. If from a business / functional viewpoint it's enough to have two persons then alternative 2 is the way to go. If on the other hand you want a complete history of persons how updated the message and also the one who created it (this will always be exactly one) you end up with one navigation property Message.Creator (exactly one) and Message.Updaters (0 to many). You see? From the person's viewpoint they may be the creator of messages (0 to many) or updater of messages (0 to many).

Youp Bernoulli
  • 5,303
  • 5
  • 39
  • 59
  • Thanks for your answer. I didn't collapse the navigation properties on `Person`. In fact, I selected to not generate navigation properties when I created the association. I never need to go from `Person` to `Message`. Also a Person is only linked to one `Message`. As for nullability, as I understand, nullable means it can be there but doesn't have to be there or 0..1. From the `Message` perspective this is pretty clear. Person1 has to be there, Person2 is optional. However, the two associations imply that a `Person` could have more than one `Message`. I will update the question to clarify. – Matthijs Wessels Jan 27 '11 at 12:14
0

Phew...Fortunately you saw the importance of decompiling the message entity into more logical and reusable entities like person, message and adress. In my humble opinion you should have this design ->

re-design

Hence the Person entity was born. However, this might look like a Person can be linked to many messages, but this is not the case. There can be two different persons with the same properties. There is no way of telling whether these persons are actually the same person in real life or not.

This sounds so strange to me...Although there might be incorrect input e.g. two persons reflecting one real-life person but with typo's for instance. But still a person could have more messages or not... And when it's really not the case you can handle this in your business code to prevent a specific person to be coupled to more than one message...

**** Update *****

I should model it this way:

My design

Youp Bernoulli
  • 5,303
  • 5
  • 39
  • 59
  • Say someone creates a message about Bob (=Person1, Person2=null). He says Bob this and Bob that. Then submits the message. Then someone else creates a message and fills in Bob as Person1. It is unlikely that it's about the same Bob, so there is in fact no relation between the two Person objects. They are two objects (representing different people) who happen to have the same properties, but linked to a different Message. You could replace Person with Subject, where Subject consists of several parts. Two messages can have a Subject with the same properties, but that are not linked at all. – Matthijs Wessels Jan 27 '11 at 14:57
  • When you don't want to re-use the person entities and it's purely for displaying a name of a person the message was about. Then just stick with your initial design of a Message entity with a Person1Name and Person2Name string properties. Simple. – Youp Bernoulli Jan 27 '11 at 15:44
  • The problem with that solution is that I will have an arbitrary amount of duplicate properties (fname, lname, gender, hair color, etc.). Furthermore, if the Message entity will have more of these associations with Person like entity (e.g. Address) then Message will become huge. That's why from a database point of view it will probably all go into the Message table for efficiency. But from a classes point of view I would create a Person class (or struct) and an Address class. You can see why this is giving me a headache. I just thought of another possible way and will update the question. – Matthijs Wessels Jan 28 '11 at 08:23