Fluent Nhibernate 多对多问题
我有三个表:
- Person (Id, FirstName)
- Organization (Id, Name)
- 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()
我的问题是:
- 我的映射是否正确设置以支持这种多对多场景?
- 有没有办法让我能够执行以下操作(这将写入所有三个表):
-
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:
- Person (Id, FirstName)
- Organization (Id, Name)
- 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:
- Are my mappings correctly setup to support this kind of many-to-many scenario?
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您需要将新创建的
PeopleOrganization
添加到两个实体(Organization
和People
)的集合中。然后,如果您将Cascade.All()
添加到HasMany
链,则保存应向下传播(级联)到PeopleOrganization
,然后传播到组织
。作为纯粹的语义建议,我建议将
PeopleOrganization
创建封装到Person
上的方法中。像这样的事情:这样你就不必自己创建 intrim 实体。
Firstly, you'll need to add your newly created
PeopleOrganization
to the collection on both entities (Organization
andPeople
). Then if you add aCascade.All()
to yourHasMany
chain, the saves should propagate (cascade) down to thePeopleOrganization
and subsequently toOrganization
.As a purely semantic suggestion, I'd recommend encapsulating the
PeopleOrganization
creation into a method onPerson
. Something like this:That way you never have to deal with creating the intrim entity yourself.