天道酬勤,学无止境

流利的NHibernate多对多(Fluent NHibernate Many-to-Many)

问题

我正在使用Fluent NHibernate,但在与我的一个班级建立多对多关系时遇到了一些问题。 这可能是一个愚蠢的错误,但为了使它正常工作,我已经被卡住了一点。 无论如何,我有几个具有很多关系的课程。

public class Person
{
    public Person()
    {
        GroupsOwned = new List<Groups>();
    }

    public virtual IList<Groups> GroupsOwned { get; set; }
}

public class Groups
{
    public Groups()
    {
        Admins= new List<Person>();
    }

    public virtual IList<Person> Admins{ get; set; }
}

映射看起来像这样

人: ...

HasManyToMany<Groups>(x => x.GroupsOwned)
    .WithTableName("GroupAdministrators")
    .WithParentKeyColumn("PersonID")
    .WithChildKeyColumn("GroupID")
    .Cascade.SaveUpdate();

群组:...

 HasManyToMany<Person>(x => x.Admins)
    .WithTableName("GroupAdministrators")
    .WithParentKeyColumn("GroupID")
    .WithChildKeyColumn("PersonID")
    .Cascade.SaveUpdate();

当我运行集成测试时,基本上是在创建一个新的人员和组。 将组添加到Person.GroupsOwned。 如果从存储库取回Person对象,则GroupsOwned等于初始组,但是,如果我检查Group.Admins的计数,则取回该组时,计数为0。Join表具有GroupID和PersonID已保存在其中。

感谢您的任何建议。

回答1

它向表中添加了两个记录这一事实看起来像您缺少逆属性。 由于人和组都被更改,因此NHibernate将关系保持两次(每个对象一次)。 反向属性专门用于避免这种情况。

我不确定如何在代码映射中添加它,但是该链接显示了如何在XML中添加它。

回答2

@圣地亚哥,我认为你是对的。

答案可能只是您需要删除您的ManyToMany声明中的一个,对Fluent进行更多研究,看起来它足够聪明才能为您执行此操作。

回答3

您确定要将该人添加到Groups.Admin中吗? 您必须同时建立两个链接。

回答4

你有三张桌子吧?

人员,组和组管理员

当您添加到双方时,您会得到

人(id为p1)群组(id为g1)

在GroupAdministrators中,您有两列和一个表

(p1,g1)

(p1,g1)

并且您的单元测试代码如下所示。

Context hibContext //Built here
Transaction hibTrans //build and start the transaction.

Person p1 = new Person()
Groups g1 = new Groups()

p1.getGroupsOwned().add(g1)
g1.getAdmins().add(p1)

hibTrans.commit();
hibContext.close();

然后在测试中创建一个新的上下文,并进行测试以查看上下文中的内容,然后返回正确的内容,但是您的表全都被破坏了?

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 多对多,带有额外列nhibernate(many-to-many with extra columns nhibernate)
    问题 所以我有两个表Users和Groups 。 这些表(在数据库中)与UGlink链接表UGlink 。 现在,除了主外键之外,链接表还有一个额外的列: Date 。 据我了解,这意味着我必须有两个“多对一”,链接位于“中间”。 但是,由于我几乎从不对额外的列值感兴趣,因此仍然有必要避免链接吗? 那就是我希望能够写: thisUser.Groups 获取组,而不是: thisUser.UGlinks.Group 回答1 在many-to-many ,无配对表作为一个实体的显式映射-在NHibernate的当然支载。 因此,万一Date列是自动生成的或可为空(不必由app / NHiberante插入) ,我们可以这样做:6.8。 双向关联 <class name="User"> <id name="Id" column="Uid"/> ... <bag name="Groups" table="UGlink" lazy="true"> <key column="Uid"/> <many-to-many class="Group" column="Gid"/> </bag> </class> <class name="Group"> <id name="id" column="Gid"/> ... <!-- inverse end --> <bag name="Users"
  • Nhibernate:如何用一对多关系表示多对多关系?(Nhibernate: How to represent Many-To-Many relationships with One-to-Many relationships?)
    问题 我已经在互联网上阅读了一篇帖子(我再也找不到该帖子供我参考),可以将一对多关系替换为一对多关系。 有人可以提供例子吗? 回答1 我只是提出这个问题,并意识到,缺少任何答案。 很遗憾,尽管我经常指出NHibernate文档声明:24.最佳实践 不要使用奇异的关联映射。 真正的多对多关联的好用例很少。 大多数时候,您需要存储在“链接表”中的其他信息。 在这种情况下,对中间链接类使用两个一对多关联会更好。 实际上,我们认为大多数关联是一对多和多对一的,在使用任何其他关联样式时,请务必小心,并问问自己是否真的必要。 看一下23.2下的示例。 作者/作品。 摘录, Author与Work之间多对多关系的简化版本: <class name="Work" table="works" ...> <id name="Id" column="id" generator="native" /> ... <set name="Authors" table="author_work" lazy="true"> <key> <column name="work_id" not-null="true"/> </key> <many-to-many class="Author"> <column name="author_id" not-null="true"/> </many-to-many> </set
  • 流利的API,在Entity Framework Core中是多对多的(Fluent API, many-to-many in Entity Framework Core)
    问题 我已经在stackoverflow上搜索了使用EF Core,Code first和Fluent API生成多对多关系的正确解决方案。 一个简单的场景是: public class Person { public Person() { Clubs = new HashSet<Club>(); } public int PersonId { get; set; } public virtual ICollection<Club> Clubs { get; set; } } public class Club { public Club() { Persons = new HashSet<Person>(); } public int ClubId { get; set; } public virtual ICollection<Person> Persons { get; set; } } 如果我做错了,请纠正我,但老实说我找不到包含有关如何使用上述工具进行详细说明的问题。 谁能解释这是怎么做的? 回答1 EF核心5.0 RC1 + 从EF Core 5.0 RC1开始,可以在没有显式联接表的情况下执行此操作。 EF Core能够为问题中显示的多对多关系配置映射,而无需您创建PersonClub类型。 有关更多信息,请参阅官方文档中的EF Core 5.0,RC1
  • 多对多映射表(Many-to-many mapping table)
    问题 从我在网上和《编程实体框架》 CodeFirst书中看到的示例中,当您在两个类上都有一个集合时,EF会创建一个映射表,例如MembersRecipes ,每个类的主键都将链接到该表。 但是,当我执行以下操作时,我改为在Recipes表中获得一个名为Member_Id的新字段,并在Members表中获得一个Recipe_Id 。 这只会创建两个一对多的关系,而不是一对多的关系,因此我可以将Member 3链接到食谱(4,5,6),将Recipe 4链接到成员(1,2,3)等。 有没有创建此映射表的方法? 如果是的话,您如何命名其他名称,例如“ cookbooks”? 谢谢 public abstract class Entity { [Required] public int Id { get; set; } } public class Member : Entity { [Required] public string Name { get; set; } public virtual IList<Recipe> Recipes { get; set; } } public class Recipe : Entity { [Required] public string Name { get; set; } [ForeignKey("Author")] public int
  • NHibernate-使用连接/联接表进行多对多查询(NHibernate - Many to Many Query using Junction/Joiner Table)
    问题 我在这里找到了非常相似的问题,但没有一个与我所寻找的完全匹配。 我发现的两个最接近的线程是(是的,它们是不同的线程): NHibernate多对多标准(1) NHibernate多对多标准(2) 但是,我认为这两个都使用直接的多对多关系。 我实际上是通过与联结表建立两个一对多关系来模拟多对多关系,这是非常标准的做法。 这是我的NHibernate映射: 档案: <class name="Files" table="files"> <id name="id"> <generator class="identity" /> </id> <property name="name" /> <bag name="files_attrs" table="files_attrs" lazy="true"> <key column="file_id" /> <one-to-many class="Files_Attrs" /> </bag> </class> 属性: <class name="Attrs" table="attrs"> <id name="id"> <generator class="identity" /> </id> <property name="name" /> <property name="value" /> <bag name="files_attrs"
  • 一对多,多对一和多对多的区别?(Difference Between One-to-Many, Many-to-One and Many-to-Many?)
    问题 好的,所以这可能是一个琐碎的问题,但是我在可视化和理解差异以及何时使用它们方面遇到困难。 对于诸如单向和双向映射之类的概念如何影响一对多/多对多关系,我也还不清楚。 我现在正在使用Hibernate,因此任何与ORM相关的解释都将有所帮助。 举例来说,我有以下设置: public class Person{ private Long personId; private Set<Skill> skills; //Getters and setters } public class Skill{ private Long skillId; private String skillName; //Getters and setters } 那么在这种情况下,我将进行哪种映射? 对于这个特定示例的答案肯定会受到赞赏,但我也确实希望获得何时使用一对多和多对多以及何时使用联接表与联接列以及单向与双向的概述。 回答1 一对多:一个人有很多技能,一个技能不会在一个人之间重复使用 单向性:一个人可以通过其设置直接参考技能双向的:每个“子级”技能都有一个指向该人的单个指针(代码中未显示) 多对多:一个人有很多技能,一种技能在人与人之间重复使用 单向性:一个人可以通过其设置直接参考技能双向的:一项技能具有一组与此相关的人。 在一对多关系中,一个对象是“父”对象,一个对象是“子”对象。
  • 如何使用流利的NHibernate将枚举映射为int值?(How do you map an enum as an int value with fluent NHibernate?)
    问题 问题确实如此,默认是将其映射为string但我需要将其映射为int 。 我目前正在使用PersistenceModel来设置我的约定,如果有什么不同的话。 提前致谢。 更新发现从主干上获取最新版本的代码解决了我的麻烦。 回答1 定义此约定的方式有时是在以前更改的,现在是: public class EnumConvention : IUserTypeConvention { public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) { criteria.Expect(x => x.Property.PropertyType.IsEnum); } public void Apply(IPropertyInstance target) { target.CustomType(target.Property.PropertyType); } } 回答2 因此,如上所述,从后备箱中获取最新版本的Fluent NHibernate将我带到了我需要的地方。 具有最新代码的枚举的映射示例为: Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus)); 自定义类型强制将其作为枚举的实例进行处理,而不是使用GenericEnumMapper<TEnum
  • 如何创建NHibernate HasManyToMany关系(How to create NHibernate HasManyToMany relation)
    问题 我知道有关于HasManyToMany的问题,但是这次我想将几个字段放入“ Description,CreationDate”之类的中间表中。 对于我的情况,我不想绑定两种方式。 我有公司,人员和地址表。 每个公司或个人可能有多个地址。 在这种情况下我该怎么办? 我应该如何编写类和映射的代码? 您可以在下面看到表格: 回答1 在这种情况下,答案很简单。 不要使用多对多。 使用配对对象。 正是由于您提到的原因:使用更多属性扩展了配对对象: 在这里查看24.最佳实践,引用: 不要使用奇异的关联映射。 真正的多对多关联的好用例很少。 大多数时候,您需要存储在“链接表”中的其他信息。 在这种情况下,对中间链接类使用两个一对多关联会更好。 实际上,我们认为大多数关联是一对多和多对一的,使用任何其他关联样式时都应小心,并问自己是否真的必要。 换句话说,创建one-to-many关系从boht两端闯民宅的配对对象, many-to-one从配对对象。 还要检查以下内容: Hibernate:多对多关系表作为实体 NHibernate双向多对多映射列表/包 Nhibernate:如何用一对多关系表示多对多关系? 地址和公司的示例。 第一个配对对象 public class AddressCompany { // the relation to both sides public
  • fluent nhibernate - many-to-many relationship mapping on same entity
    I am having a problem trying to map out a many-to-many relationship , where both sides of the relationship reference the same entity. I am using Fluent NHibernate and NH3.1. Basically, the scenario is this - I have a category, which can have multiple parents. Thus, a category has multiple other categories as parents, as well as multiple other categories as its children. HasManyToMany(x => x.ParentCategories).AsBag().Table("parentcategorychildren").ParentKeyColumn("ChildID").ChildKeyColumn("ParentID").Cascade.SaveUpdate(); HasManyToMany(x => x.ChildrenCategories).AsBag().Table(
  • Fluent NHibernate Many-to-Many
    I am using Fluent NHibernate and having some issues getting a many to many relationship setup with one of my classes. It's probably a stupid mistake but I've been stuck for a little bit trying to get it working. Anyways, I have a couple classes that have Many-Many relationships. public class Person { public Person() { GroupsOwned = new List<Groups>(); } public virtual IList<Groups> GroupsOwned { get; set; } } public class Groups { public Groups() { Admins= new List<Person>(); } public virtual IList<Person> Admins{ get; set; } } With the mapping looking like this Person: ... HasManyToMany
  • 从流畅的Nhibernate生成XML映射(Generate XML mappings from fluent Nhibernate)
    问题 如何在MappingIntegrationTests中的测试中生成xml映射文件 我需要手动检查流利的映射是否与旧项目中的映射相关。 回答1 您可以执行以下操作: config.Mappings(m => { m.FluentMappings.ExportTo("...file path here..."); m.HbmMappings.ExportTo("...file path here..."); m.AutoMappings.ExportTo("...file path here..."); { ); 我自己不喜欢如果我找到更好的方法(如果确实存在),我将更新答案。 看 http://blog.jagregory.com/2009/02/03/fluent-nhibernate-configuring-your-application/ 或者,如果损坏,请改为查看此内容 https://github.com/jagregory/fluent-nhibernate/wiki/数据库配置 回答2 您可以通过调用ExportTo()方法来生成XML映射。 例如: ISessionFactory sessionFactory = FluentNHibernate.Cfg.Fluently.Configure() .Database(FluentNHibernate.Cfg
  • 流利的接口-方法链接(Fluent Interfaces - Method Chaining)
    问题 方法链接是我知道的建立流畅接口的唯一方法。 这是C#中的示例: John john = new JohnBuilder() .AddSmartCode("c#") .WithfluentInterface("Please") .ButHow("Dunno"); Assert.IsNotNull(john); [Test] public void Should_Assign_Due_Date_With_7DayTermsVia_Invoice_Builder() { DateTime now = DateTime.Now; IInvoice invoice = new InvoiceBuilder() .IssuedOn(now) .WithInvoiceNumber(40) .WithPaymentTerms(PaymentTerms.SevenDays) .Generate(); Assert.IsTrue(invoice.DateDue == now.AddDays(7)); } 那么其他人如何创建流畅的界面。 您如何创建它? 需要什么语言/平台/技术? 回答1 您可以使用任何版本的.NET或任何其他面向对象的语言来创建流畅的界面。 您需要做的就是创建一个对象,该对象的方法始终返回该对象本身。 例如在C#中: public class JohnBuilder {
  • 自引用多对多递归关系代码优先实体框架(Self-referencing many-to-many recursive relationship code first Entity Framework)
    问题 我似乎根本无法完成这项工作 class Member { public virtual IList<Member> Friends { get; set; } [Key] public int MemberId { get; set; } public string Name{ get; set; } } 我尝试添加映射,但徒劳无功。 有没有办法用CTP5做到这一点? 回答1 按照惯例,Code First将单向关联视为一对多。 因此,您需要使用流利的API来让Code First知道您希望拥有多对多的自引用关联: protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Member>().HasMany(m => m.Friends).WithMany().Map(m => { m.MapLeftKey("MemberId"); m.MapRightKey("FriendId"); m.ToTable("MembersFriends"); } ); } 回答2 如果我是正确的,那么您可以使用以下代码来影响多对多表名: protected override void OnModelCreating(ModelBuilder modelBuilder) {
  • How to map IDictionary<string, Entity> in Fluent NHibernate
    I have an class with an IDictionary on it. <map name="CodedExamples" table="tOwnedCodedExample"> <key> <column name="OwnerClassID"/> </key> <index type="string" column="ExampleCode"/> <many-to-many class="CodedExample" column ="CodedExampleClassID"/> </map> as you can see it uses a many-to-many to get the CodedExamples from their table using the tOwnedCodedExample table to find which are owned by the OwnerClass. I realise that this is a very basic (and hopefully standard) mapping but am struggling and can't find any documentation for it, therefore would be very grateful of any help possible
  • 如何在实体框架中创建多对多映射?(How to create a many-to-many mapping in Entity Framework?)
    问题 在这种情况下,我有2个实体,例如Contract,Media。 public class Media : Entity { public string Name {get; set;} public bool Enabled *//other properties can be ignored..* } public class Contract : Entity { public string Code {get; set;} *//other properties can be ignored..* } 合同有许多媒体,看来它们是多对多的。 但!! 首先在EF代码,我需要在ContractMedia表(EF自动生成)中再添加3个字段。 例如StartDate,EndDate和Price。 无法将其添加到媒体实体中。 在这种情况下如何映射? 回答1 如果要使用关联表中的其他数据创建多对多关系,则必须将关联表作为实体。 纯多对多关系仅在具有实体ID的纯表中。 在您的情况下,它将是: public class Media // One entity table { public int Id { get; set; } public string Name { get; set; } public bool Enabled { get; set; } public
  • Fluent NHibernate HasManyToMany() Mapping
    I am having a problem in Fluent NHibernate example utilizing the Many-to-Many relationships. I tried to find out examples on a similar case, and I found tons, but I'm still having the same problem. When running the test project, the following exception is thrown: NHibernate.PropertyAccessException: Exception occurred getter of project.Entities.User.UserName ---> System.Reflection.TargetException: Object does not match target type. This is an image of the tables: and the code public UsersMap() { this.Table("Users"); Id(x => x.UserName).Column("Username").GeneratedBy.Assigned(); Map(x => x
  • Can I make a Fluent NHibernate foreign key convention which includes parent key name?
    I have a database schema where the convention for a foreign key's name is: ForeignTable.Name + ForeignTable.PrimaryKeyName So, for a Child table referencing a Parent table with a primary key column named Key, the foreign key will look like ParentKey. Is there a way to create this convention in my Fluent NHibernate mapping? Currently I'm using a ForeignKeyConvention implementation like this: public class ForeignKeyNamingConvention : ForeignKeyConvention { protected override string GetKeyName(PropertyInfo property, Type type) { if (property == null) { // Relationship is many-to-many, one-to-many
  • 多对多自我参照关系(Many-to-many self referencing relationship)
    问题 我是EF的新手。 而且我遇到了创建多对多自引用关系的问题。 我尝试使用以下解决方案:实体框架核心:同一实体的多对多关系 我的实体: public class WordEntity { public long Id { get; set; } public string Name { get; set; } public string Json { get; set; } public virtual List<WordSinonymEntity> Sinonyms { get; set; } } public class WordSinonymEntity { public long WordId { get; set; } public virtual WordEntity Word { get; set; } public long SinonymId { get; set; } public virtual WordEntity Sinonym { get; set; } } 和下一个配置: modelBuilder.Entity<WordSinonymEntity>() .HasOne(pt => pt.Sinonym) .WithMany(p => p.Sinonyms) .HasForeignKey(pt => pt.SinonymId)
  • Set up caching on entities and relationships in Fluent Nhibernate?
    Does anyone have an example how to set up and what entities to cache in fluent nhibernate. Both using fluent mapping and auto mapping? And the same for entity relationships, both one-to-many and many-to-many?
  • .net ORM比较[关闭](.net ORM Comparison [closed])
    问题 从目前的情况来看,这个问题不适合我们的问答形式。 我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意测验或进一步的讨论。 如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 我正在和某人谈论实体框架,但我还没有真正了解它,但是我想学习它。 但是,我是否应该学习还是有点困惑。 我听过很多人说您不应该使用实体框架,但是我没有听到任何关于为什么这样做的争论。 所以我的问题是,与其他产品相比,使用实体框架的优缺点是什么? 喜欢 NHibernate DataObjects.Net 等等.. 在易用性,可测试性,语义方面... 我知道对此有一些重复的问题。 但是它们都有些过时(2008年,2009年),说实话,这些论点也缺乏一些东西。 我知道可以使用Entity Framework 4.0,但是还没有找到很好的(完整的)比较。 答案 这里的一些好人通过解释有关不同框架的一些细节回答了我的问题。 认为在这里显示它们以备将来参考可能会很好。 J. Tihon撰写了出色的文章,解释了当您需要更多扩展性时如何使EF正常工作。 Diego Mijelshon用EF的一些缺陷以及NHibernate如何解决这些缺陷创造了一个答案。 回答1 由于J. Tihon在解释EF功能方面做得很出色