如何在代码中建模多对多关系?假设我在数据库中有2个表。例如:Dog&Boss这是多对多的关系,因为老板可以有不止一只狗,而一只狗可以有不止一个主人。我是鲍比的老板,但我妻子也是。但是很多人不允许这样做,所以这里有一个很好的帮助:HowisDogsPerBossmodeledincode?班级所有者可以拥有一组狗。类狗可以有一系列的老板。->至少,我是这么认为的。也许有更好的解决方案?辅助表中的额外数据怎么办?这个应该是boss级还是狗级?示例:昵称(我称这只狗为“好孩子”,我妻子称他为“小狗”)希望我的问题有点清楚?实现这一目标的最佳方法是什么?你能给我一些参考吗?ORM(如NHibernate)不是一个选项。你为什么要谈论桌子?您是在创建对象模型还是数据库模型?对于对象模型,没有理由狗不能拥有列表,而所有者拥有列表。只有在关系上有属性时才需要中间类(UML称之为关联类)。那时你有一个带有额外属性的DogOwnership类,每个所有者都有一个列表,每只狗都有。DogOwner将拥有狗、主人和其他财产。公共类Boss{私有字符串名称;私人名单狗;私人限制;publicBoss(stringname,intdogLimit){this.name=name;this.dogs=newList();this.limit=dogLimit;}publicstringName{get{returnthis.name;}}publicvoidAddDog(stringnickname,Dogdog){if(!this.dogs.Contains(nickname)&&!this.dogs.Count==limit){this.dogs.Add(nickname,dog);dog.AddBoss(这个);}}publicvoidRemoveDog(字符串昵称){this.dogs.Remove(昵称);dog.RemoveBoss(这个);}publicvoidHashtableDogs{get{returnthis.dogs;}}}publicclassDog{私有字符串名称;私人名单老板;公共狗(字符串名称){this.name=name;this.bosses=newList();}publicstringName{get{returnthis.name;}}publicvoidAddBoss(Bossboss){if(!this.bosses.Contains(boss)){this.bosses.Add(boss);}}publicvoidRemoveBoss(Bossboss){this.bosses.Remove(boss);}publicReadOnlyCollectionBosses{get{returnnewReadOnlyCollection(this.bosses);}}}上面维护了老板可以有多只狗(有限制)和狗有多个老板的关系这也意味着当老板添加狗时,他们可以给狗分配一个昵称,昵称只对那个老板唯一.这意味着其他老板可以添加同一条狗,但昵称不同。至于限制,我可能会把它作为App.Config值,您在实例化老板对象之前阅读它。所以一个小例子是:varjames=newBoss("James",ConfigurationManager.AppSettings["DogsPerBoss"]);varjoe=newBoss("Joe",ConfigurationManager.AppSettings["DogsPerBoss"]);varbenji=newDog("Benji");varpooch=newDog("Pooch");james.AddDog("好孩子",benji);joe.AddDog("小狗",benji);james.AddDog("Rover",pooch);joe.AddDog("Buddy",pooch);//不会添加,因为已达到预设限制。您可以根据需要对其进行调整,但是,我认为您正在寻找的理由是存在的。像这样的东西;它仍然需要一些微调(将集合设为私有,并向其添加只读公共访问器,例如返回readonlycollection,但你会发现漂移。publicclassDog{publicListBosses;publicvoidAddBoss(Bossb){if(b!=null&&Bosses.Contains(b)==false){Bosses.Add(b);b.AddDog(这个);}}publicvoidRemoveBoss(Bossb){if(b!=null&&Bosses.Contains(b)){Bosses.Remove(b);b.RemoveDog(这个);}}}publicclassBoss{publicListDogs;publicvoidAddDog(Dogd){if(d!=null&&Dogs.Contains(d)==false){Dogs.Add(d);d.AddBoss(这个);}}publicvoidRemoveDog(Dogd){if(d!=null&&Dogs.Contains(d)){Dogs.Remove(d);d.RemoveBoss(这个);这样你就可以在代码中建模多对多,其中每只狗都认识他的老板,每个老板都认识他的狗。当您需要辅助表中的其他数据时,您还需要创建另一个类。这是数据库之间的经典问题,多对多不起作用,因此您的帮助表和多对多工作正常的对象世界。一旦关系具有属性,那么您应该创建一个新类来保存该信息。但是如果你看看对象关系映射(ORM)那么你会节省很多时间,整个领域已经发展到解决DB和对象之间的这个(以及许多其他)问题。如果您有一个简单的多对多链接表,其中包含关系中每个表的外键,那么您可以按照您的建议对其进行建模:Boss有一个Dogs的集合,Dog有一个Bosses的集合。如果您与昵称等额外数据存在多对多关系,则可以将其建模为两个一对多关系。创建一个实体,比如DogBoss,这样Boss就有一个DogBoss的集合,而Dog有一个DogBoss的集合。传统的多对多关系在匹配表上没有额外的字段。由于您确实拥有包含独特信息的字段,因此我倾向于不再考虑这些关系。将信息添加到匹配表后,我认为您已经将表本身变成了一个实体,因此它需要自己的对象来表示它。此时,您可以开始使用DogsName类来连接人和狗-两个类都包含对此对象的引用作为集合的一部分。但是,您是否给狗起名字或拥有狗是独立的。除了根据不同的人对狗名关系进行建模外,您还需要对所有权关系进行建模。在内存中,这意味着两个对象都包含其他对象的列表。如果不需要记录昵称,那么Dog应该有一个boss列表,boss应该有一个dog列表。如果Dog和Boss之间的关系有一个属性,在本例中是昵称,那么您应该创建一个表示该关系的类,并让Dog和Boss都持有该类型的列表。我使用NHibernate有一段时间了,发现它在缓解这种对象关系阻抗不匹配方面非常有用。我想我错过了什么。为什么很多人不允许?公共课Boss{Dog[]dogs;}publicclassDog{Boss[]老板;在关系模型中,模拟多对多关系(使用Dogs/Bosses示例)的最佳方法是拥有三个单独的表。一张表给DOGS,一张表给BOSSES(而且每张表都有一个唯一的key),第三张表通常就是“jointable”。这张表通常至少有两个字段,一个是Dog的外键,一个是Boss的外键。这样每只狗可以有很多老板,每个老板可以有很多狗。现在,当它以更面向对象的方式在代码中建模时,通常是通过拥有一个Dog类和一个Boss类。除了为每个对象提供通常的基本属性外,每个对象还公开一个属性,该属性是另一个对象的集合。因此,例如,Dog对象将具有一个名为“Bosses”的属性。此属性将公开分配给特定Dog对象(如联结表中定义)的Boss对象的集合,另一方面,每个Boss对象将公开一个名为Dogs的属性,该属性将是分配给特定Boss的Dog对象的集合对象(由联结表定义)。请注意,这些对象中可能存在一些“重叠”(即一个“狗”对象可能具有另一个“狗”对象具有的“老板”对象),但是,这是翻译三个表的传统机制–转换多个关系模型转化为面向对象的模型。我是不是遗漏了什么,或者是你需要的唯一代码,像这样:ListBossList;classDog{}classBoss{Dog[]Dogs;您不需要显式建模双向关系。它隐含在代码结构中。可能还有其他原因,但通常只有单向引用和一种遍历引用对象集的方法就足够了。每当我们需要考虑现实生活和我们的需求时。在这种情况下,关键是哪个应该有另一个。在现实生活中,狗和主人可能没有彼此。但是您的软件要求应该会影响这种关系。–如果你的软件是为治疗被主人收养的流浪狗的兽医开发的,那么你的设计应该是这样的,任何狗都可能没有主人,并且任何主人在收养之前都可能没有任何狗。在这种情况下,我们的OO设计需要处理这种特殊情况。这个案例与第一个案例略有不同。所以我们可以将任何类的集合添加到其他类中。但是,任何此类软件要求都会影响其他要求。比如举报。如果兽医对主人收养的狗有疑虑,他迟早会要求提供一份关于谁收养了哪只狗的报告。就像在句子中,(老板收养的狗)如果狗类包含老板类的集合会更好。我希望我能对你的问题给出正确的答案。不确定您的要求。但这是你想要的表结构:DogtableDOG_IDintPKDOG_Namevarchar(50)DogsPerBossIDintDOG_IDintBOSS_IDintDogNickNamevarchar(15)BossBOSS_IDintPKBOSS_Namevarchar(50)以上是C#学习教程:去建模多对多关系?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
