流利Nhibernate多对多的问题 [英] Fluent Nhibernate many-to-many issue
问题描述
$ b $ ol
当我第一次用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()
我的问题是:
- 我的映射是否正确设置以支持这种多对多场景?
- 是否有办法让我能够(这将写入所有三个表):
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:
- 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
解决方案 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屋!