如何在 EF 中对 2 的重数进行建模
我有两种情况想要这样的东西。在我的模型中,我有一个涉及一个或两个人的消息
。此外,该消息与两个地址
相关联,即一个来自地址
和一个到地址
。
在第一种情况下,有两个 Persons
,我想指定 Message
和 Person
重数 1---1 之间的关联。 2 或指定两个关联,一个与 1---1,另一个与 1---0..1。但是,我无法(或不知道如何)将多重性设置为二。我可以想象,可以将其设置为 1--*,并将约束设置为最大 2(但我不知道该怎么做)。
通过添加这两个关联,当我查看 Message
一侧时,我感觉有点奇怪,因为两个关联都有一个 1,这表明 Person
应该有两个 Message与此相关。我可能想要在
Message
一侧为两个关联添加类似 0..1 的值,并对其进行异或约束或其他操作,但我不知道这在 EF 中是否是一个好的实践,甚至是否可能。
对于第二种情况,问题非常相似,除了有始终是“发件人地址”,并且始终是“收件人地址”。设置重数 1--* 对我来说似乎不正确。在这里,我想肯定应该有两个关联,一个 from 和一个 to 关联(它们恰好都指向 Address
实体)。然而,这会导致 Message
端出现同样的问题,即有两个 1 或两个 0..1。
所以我的问题是,如何在 EDM 中正确建模?
提前致谢。
更新 1:
为了澄清这个问题,我将提供一些背景信息来说明为什么我需要这样一个模型。我必须能够创建一条消息。在这条消息中,我必须具体说明它是涉及一个人还是两个人。在这些人中,我指定了名字、姓氏和一些其他非唯一属性(两个人可以具有相同的名字)。我可以将所有这些属性转储到 Message
实体中(fname1、lname1、fname2、lname2),但这似乎是一个坏主意。因此,Person
实体诞生了。但是,这可能看起来一个 Person
可以链接到许多消息,但事实并非如此。可以有两个不同的人具有相同的属性。无法判断这些人是否是现实生活中的同一个人。
对于地址,也存在类似的论点。两个地址的拼写可能略有不同,但如果我将它们写在一封信上并邮寄,它们都会到达相同的位置(例如 sesamestreet 或 sesamestr.)。因此,我没有一个 Address
实体连接到多个 Messages
。同样,Address
是一个单独的实体的唯一原因是因为我有两个具有完全相同属性的地址。 从数据库设计的角度来看,这可能没有意义,从类图的角度来看,这可能更有意义。我的印象是 EF 中的 EDM 不应该像数据库设计,而更像是领域模型,所以我希望我做了正确的事情。
更新2:
我只是想到了在这种情况下我认为最好的方法。因为 Person1
和 Person2
之间几乎没有区别,所以我想在 Message
和 Person
1 之间建立关联。 .* 可以接受。事实上,许多意味着两个将由较低层处理。在地址情况下,from 和 to 是完全不同的。它们都是地址,但我觉得我无法将它们列出。我可以将 from 和 to 地址拆分为单独的实体,并让它们从 Address
继承。然后将 Message
与每个子类相关联。这可能看起来有点矫枉过正,但您可能会推断,发件人地址可能在某些时候与目标地址具有不同的要求,因此具有不同的属性。
不过我并不是 100% 满意(尤其是地址部分)。这个解决方案可能会也可能不会,但我觉得它避免了核心问题。
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.
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.
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.
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.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于第一个问题(消息 - 人员):
关键问题是:您希望 person1 不可为空吗?还有人2?
您所描绘的第二个替代方案对我来说看起来相当不错,因为您需要一条消息恰好有 1 个 Person1 (例如:消息的创建者),因此是一个不可为 null 的属性。 Person2(例如:最后更新消息的人)可以为空或链接到现有人员。美好的!
从 person 类的角度来看,您看到的是它有两个关联(以及 2 个导航属性,您将其折叠...),一个用于特定人员(人员实体的实例)是其创建者的消息,另一个用于这些消息这个特定的人是最后一个更新者。相当不错!不是吗?这样,您可以从消息的角度查询模型(给我所有消息以及创建它和最后更新它的每条消息的人员...)或者...查询一个人并收集此人的所有消息创建或者是最后一个更新者...明白吗?
但一切都取决于确定是否允许 Person1 和 Person2 为空。
我没有读你的第二个问题,但认为它更像是一样的。也需要一些建议吗?给我打电话吧。
此外。如果从业务/功能的角度来看,两个人就足够了,那么替代方案 2 就是最佳选择。另一方面,如果您想要有关人员如何更新消息以及创建消息的人的完整历史记录(这始终是一个),您最终会得到一个导航属性 Message.Creator (恰好是一个)和 Message.Updaters ( 0 到多个)。你看?从人的角度来看,他们可能是消息的创建者(0 到许多)或消息的更新者(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).
唷...幸运的是,您看到了将消息实体反编译为更符合逻辑和可重用的实体(例如人员、消息和地址)的重要性。以我的拙见,你应该有这样的设计 ->
这对我来说听起来很奇怪......尽管可能存在不正确的输入,例如两个人反映一个现实生活中的人,但例如有拼写错误。但一个人仍然可以有更多消息或没有更多消息...当情况确实不是这样时,您可以在业务代码中处理这个问题,以防止特定的人耦合到多个消息...
**** 更新 * ****
我应该这样建模:
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 ->
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: