流利Nhibernate多对多的问题 [英] Fluent Nhibernate many-to-many issue

查看:130
本文介绍了流利Nhibernate多对多的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个表:
$ b $ ol
  • Person(Id,FirstName)

  • 组织,名称)
  • PersonOrganization(PersonId,OrganizationId,Details)多对多表

  • 当我第一次用Fluent NHibernate映射这个时,PersonOrganization表中没有详细信息列,并且在PersonMap和OrganizationMap中使用HasManyToMany映射了这个列(不需要创建PersonOrganization域对象或映射)。我可以编写以下代码:

     组织org = new Organization {Name =org}; 
    People people = new People {FirstName =firstname,Organization = org};

    peopleRepository.Add(people); // ISession.Save(people)
    unitOfWork.Commit(); // ITransaction.Commit()

    NHhibernate乐于将数据提交给所有三个表。



    当我在PersonOrganization表中添加details列时,问题就出现了。经过一番研究后,我发现现在必须创建一个新的PersonOrganization域对象,并为Person和Organization建立一个HasMany关系。我的更新模型和地图如下:

      public class People 
    {
    public People()
    {
    LinkToOrganization = new List< PeopleOrganization>();
    }

    public virtual int Id {get;组; }
    公共虚拟字符串名字{get;组; }
    公共虚拟IList< PeopleOrganization> LinkToOrganization {get;组; }

    $ b $ public class Organization
    {
    public Organization()
    {
    LinkToPeople = new List< PeopleOrganization>();
    }

    public virtual int Id {get;组; }
    public virtual string Name {get;组; }
    公共虚拟IList< PeopleOrganization> LinkToPeople {get;组; }
    }

    public class PeopleOrganization
    {
    public virtual People People {get;组; }
    公共虚拟组织组织{get;组; }
    public virtual string Details {get;组; }
    }

    public class PeopleMap:ClassMap< People>
    {
    public PeopleMap()
    {
    Id(p => p.Id);
    Map(p => p.FirstName).Length(100);

    HasMany(x => x.LinkToOrganization)
    .Table(PeopleOrganization)
    .KeyColumn(PeopleId)
    .AsBag()
    .Inverse();
    }
    }

    public class OrganizationMap:ClassMap< Organization>
    {
    public OrganizationMap()
    {
    Id(p => p.Id);
    Map(p => p.Name).Length(50);

    HasMany(x => x.LinkToPeople)
    。表(PeopleOrganization)
    .KeyColumn(OrganizationId)
    .AsBag()
    .Inverse();
    }
    }

    public class PeopleOrganizationMap:ClassMap< PeopleOrganization>
    {
    Public PeopleOrganizationMap()
    {
    CompositeId()
    .KeyReference(p => p.People,PeopleId)
    .KeyReference (p => p.Organization,OrganizationId);

    Map(p => p.Details).Length(100);




    $ b我现在必须写下面的代码: p>

      People people = new People {FirstName =firstname}; 
    Organization org = new Organization {Name =org};
    PeopleOrganization po = new PeopleOrganization {People = people,Organization = org,Details =details};

    peopleRepository.Add(people); // ITransaction.Begin()ISession.Save(people)
    organizationRepository.Add(org); // ISession.Save(org)
    peopleOrganizationRepository.Add(po); //).session.Save(po)

    unitOfWork.Commit(); // ITransaction.Commit()

    我的问题是:


    1. 我的映射是否正确设置以支持这种多对多场景?
    2. 是否有办法让我能够(这将写入所有三个表):









        People people = new People {FirstName =firstname}; 
      Organization org = new Organization {Name =org};
      PeopleOrganization po = new PeopleOrganization {People = people,Organization = org,Details =details};

      peopleRepository.Add(people); //只是一个ISession.Save(人)

      unitOfWork.Commit(); // ITransaction.Commit()

      任何输入值得高度赞赏。



      谢谢

      解决方案

      首先,您需要添加新创建的 Organization People )上的集合然后,如果向 HasMany 链添加 Cascade.All(),则保存应该传播(级联)到 PeopleOrganization ,然后到 Organization



      作为纯粹的语义建议,我建议将 PeopleOrganization 创建封装到 Person 的方法中。就像这样:

      pre code
      $ public void AddOrganization(Organization org,string details)
      {
      var link = new PeopleOrganization {...};

      LinkToOrganization.Add(link)
      org.LinkToPeople.Add(link);




      $ b $ p
      $ b $ p这样,你永远不需要处理创建intrim实体你自己。


      I have three tables:

      1. Person (Id, FirstName)
      2. Organization (Id, Name)
      3. PersonOrganization (PersonId, OrganizationId, Details) many-to-many table

      When I first mapped this using Fluent NHibernate I did not have a details column in the PersonOrganization table and mapped this using HasManyToMany in the PersonMap and OrganizationMap (no need to create a PersonOrganization domain object or map). I could writethe following code:

      Organization org = new Organization { Name = "org" };
      People people = new People { FirstName = "firstname", Organization = org };
      
      peopleRepository.Add(people);          // ISession.Save(people)
      unitOfWork.Commit();                   // ITransaction.Commit()
      

      NHhibernate happily committed the data to all three tables.

      The issue comes up when I added the details column in the PersonOrganization table. After some research it turns out that I now have to create a new PersonOrganization domain object and map and setup a HasMany relationship for both Person and Organization. My updated model and maps below:

      public class People
      {
          public People()
          {
              LinkToOrganization = new List<PeopleOrganization>();
          }
      
          public virtual int Id { get; set; }
          public virtual string FirstName { get; set; }
          public virtual IList<PeopleOrganization> LinkToOrganization { get; set; }
      }
      
      public class Organization
      {
          public Organization()
          {
              LinkToPeople = new List<PeopleOrganization>();
          }
      
          public virtual int Id { get; set; }
          public virtual string Name { get; set; }
          public virtual IList<PeopleOrganization> LinkToPeople { get; set; }
      }
      
      public class PeopleOrganization
      {
          public virtual People People { get; set; }
          public virtual Organization Organization { get; set; }
          public virtual string Details { get; set; }
      }
      
      public class PeopleMap : ClassMap<People>
      {
          public PeopleMap()
          {
              Id(p => p.Id);
              Map(p => p.FirstName).Length(100);
      
              HasMany(x => x.LinkToOrganization)
                  .Table("PeopleOrganization")
                  .KeyColumn("PeopleId")
                  .AsBag()
                  .Inverse();
          }
      }
      
      public class OrganizationMap : ClassMap<Organization>
      {
          public OrganizationMap()
          {
              Id(p => p.Id);
              Map(p => p.Name).Length(50);
      
              HasMany(x => x.LinkToPeople)
                  .Table("PeopleOrganization")
                  .KeyColumn("OrganizationId")
                  .AsBag()
                  .Inverse();
          }
      }
      
      public class PeopleOrganizationMap : ClassMap<PeopleOrganization>
      {
          public PeopleOrganizationMap()
          {
              CompositeId()
                  .KeyReference(p => p.People, "PeopleId")
                  .KeyReference(p => p.Organization, "OrganizationId");
      
              Map(p => p.Details).Length(100);
          }
      }
      

      I now have to write the following code:

      People people = new People { FirstName = "firstname" };
      Organization org = new Organization { Name = "org" };
      PeopleOrganization po = new PeopleOrganization { People = people, Organization = org, Details = "details" };
      
      peopleRepository.Add(people);          // ITransaction.Begin() ISession.Save(people)
      organizationRepository.Add(org);       // ISession.Save(org)
      peopleOrganizationRepository.Add(po);  // ISession.Save(po)
      
      unitOfWork.Commit();                   // ITransaction.Commit()
      

      My questions are:

      1. Are my mappings correctly setup to support this kind of many-to-many scenario?
      2. Is there are way for me to just be able to do the following (which would write to all three tables):

      -

      People people = new People { FirstName = "firstname" };
      Organization org = new Organization { Name = "org" };
      PeopleOrganization po = new PeopleOrganization { People = people, Organization = org, Details = "details" };
      
      peopleRepository.Add(people);          // Just ONE ISession.Save(people)
      
      unitOfWork.Commit();                   // ITransaction.Commit()
      

      Any input is highly appreciated.

      Thanks

      解决方案

      Firstly, you'll need to add your newly created PeopleOrganization to the collection on both entities (Organization and People). Then if you add a Cascade.All() to your HasMany chain, the saves should propagate (cascade) down to the PeopleOrganization and subsequently to Organization.

      As a purely semantic suggestion, I'd recommend encapsulating the PeopleOrganization creation into a method on Person. Something like this:

      class Person
      {
        public void AddOrganization(Organization org, string details)
        {
          var link = new PeopleOrganization { ... };
      
          LinkToOrganization.Add(link)
          org.LinkToPeople.Add(link);
        }
      }
      

      That way you never have to deal with creating the intrim entity yourself.

      这篇关于流利Nhibernate多对多的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆