Fluent Nhibernate 多对多问题

发布于 2024-10-07 23:03:09 字数 3633 浏览 0 评论 0原文

我有三个表:

  1. Person (Id, FirstName)
  2. Organization (Id, Name)
  3. PersonOrganization (PersonId, OrganizationId, Details) 多对多表

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

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 愉快地将数据提交到所有三个表。

当我在 PersonOrganization 表中添加详细信息列时,出现了问题。经过一些研究后发现,我现在必须创建一个新的 PersonOrganization 域对象,并为人员和组织映射和设置 HasMany 关系。我更新的模型和地图如下:

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);
    }
}

我现在必须编写以下代码:

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()

我的问题是:

  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);          // Just ONE ISession.Save(people)

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

任何输入都将受到高度赞赏。

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自由如风 2024-10-14 23:03:09

首先,您需要将新创建的 PeopleOrganization 添加到两个实体(OrganizationPeople)的集合中。然后,如果您将 Cascade.All() 添加到 HasMany 链,则保存应向下传播(级联)到 PeopleOrganization,然后传播到组织

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

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

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

这样你就不必自己创建 intrim 实体。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文