一对多引用上的 Fluent NHibernate 重复行
Fluent NHibernate duplicate row on one-to-many reference
在我的项目中,我遇到了一对多引用的问题。
实际上我引用了三个 dto 来创建多对多引用:
- 用户一对多角色组
- Role一对多RoleGroup
一个用户可以拥有多个角色,因此一个角色可以分配给更多用户。
问题:
当我尝试按条件检索用户时(在 Fluent NHibernate 中按示例搜索)我发现了重复的行(实际上我的数据库中有 1 个用户用于 2 个角色的测试,当我搜索该用户时我看到 2 个相同的行)。
但是,如果我尝试通过其键检索用户,我会找到一行(这是正确的)。
下面你可以看到User和RoleGroup的映射class,然后是搜索的方法...你能帮我找到问题并给我一些建议吗?
非常感谢大家!
纳克
映射:
//USER MAPPING
public class UserMap : ClassMap<User>
{
public UserMap
{
this.Schema("[dbo]");
this.Table("[users]");
this.CompositeId(x => x.Key)
.KeyProperty(x => x.ApplicationId)
.KeyProperty(x => x.Id);
this.Map(x => x.Email);
this.Map(x => x.Password);
this.Map(x => x.Pin);
this.Map(x => x.FirstName);
this.Map(x => x.SecondName);
this.Map(x => x.IsActive);
this.Map(x => x.Expiring);
this.Map(x => x.DateOfBirth);
this.Map(x => x.Phone);
this.HasMany(x => x.RoleGroups)
.Not.LazyLoad()
.Cascade.AllDeleteOrphan()
.Fetch.Join()
.Inverse()
.KeyColumns.Add("applicationId", "userId");
}
}
//ROLE GROUP MAPPING
public class RoleGroupMap: ClassMap<RoleGroup>
{
public RoleGroupMap
{
this.Schema("[dbo]");
this.Table("[role_groups]");
this.CompositeId(x => x.Key)
.KeyProperty(x => x.ApplicationId)
.KeyProperty(x => x.Id);
this.Map(x => x.UserId);
this.Map(x => x.RoleId);
this.References(x => x.User)
.Not.LazyLoad()
.Not.Nullable()
.Cascade.SaveUpdate()
.Columns("applicationId", "userId");
this.References(x => x.Role)
.Not.LazyLoad()
.Not.Nullable()
.Cascade.SaveUpdate()
.Columns("applicationId", "roleId");
}
}
//FLUENT NHIBERNATE REPO
public class Repository<TIdentifier> : IRepository<TIdentifier> where TIdentifie : class, new()
{
...
//method used to search by criteria, in this particular case Item is type of User and it is used as criteria
public virtual IEnumerable<TIdentifier> LoadByCriteria(TIdentifier Item, int? RecordStartIndex = null, int? TotalRecords = null)
{
IList<Tidentifier> itemList;
using(ISession session = NHibernateConfiguration<TIdentifier>.OpenSession())
{
ICriteria criteria = session.CreateCriteria<TIdentifier>();
if(RecordStartIndex != null)
{
criteria.SetFirstResult((int)RecordStartIndex);
}
if(TotalRecords != null)
{
criteria.SetMaxResults((int)TotalRecords);
}
itemList = criteria.Add(Example.Create(Item))
.List<TIdentifier>();
}
if(itemList == null)
itemList = new List<TIdentifier>();
return itemList.ToList();
}
}
避免.Fetch.Join()
。它在 SQL 中创建连接,导致行的乘法。为避免 N+1 问题,请改用批量提取。
另请参阅:
- Criteria API: Fetch of a list returns repeated main entity
- Hibernate Subselect vs Batch Fetching
在我的项目中,我遇到了一对多引用的问题。
实际上我引用了三个 dto 来创建多对多引用:
- 用户一对多角色组
- Role一对多RoleGroup
一个用户可以拥有多个角色,因此一个角色可以分配给更多用户。
问题: 当我尝试按条件检索用户时(在 Fluent NHibernate 中按示例搜索)我发现了重复的行(实际上我的数据库中有 1 个用户用于 2 个角色的测试,当我搜索该用户时我看到 2 个相同的行)。
但是,如果我尝试通过其键检索用户,我会找到一行(这是正确的)。
下面你可以看到User和RoleGroup的映射class,然后是搜索的方法...你能帮我找到问题并给我一些建议吗?
非常感谢大家! 纳克
映射:
//USER MAPPING
public class UserMap : ClassMap<User>
{
public UserMap
{
this.Schema("[dbo]");
this.Table("[users]");
this.CompositeId(x => x.Key)
.KeyProperty(x => x.ApplicationId)
.KeyProperty(x => x.Id);
this.Map(x => x.Email);
this.Map(x => x.Password);
this.Map(x => x.Pin);
this.Map(x => x.FirstName);
this.Map(x => x.SecondName);
this.Map(x => x.IsActive);
this.Map(x => x.Expiring);
this.Map(x => x.DateOfBirth);
this.Map(x => x.Phone);
this.HasMany(x => x.RoleGroups)
.Not.LazyLoad()
.Cascade.AllDeleteOrphan()
.Fetch.Join()
.Inverse()
.KeyColumns.Add("applicationId", "userId");
}
}
//ROLE GROUP MAPPING
public class RoleGroupMap: ClassMap<RoleGroup>
{
public RoleGroupMap
{
this.Schema("[dbo]");
this.Table("[role_groups]");
this.CompositeId(x => x.Key)
.KeyProperty(x => x.ApplicationId)
.KeyProperty(x => x.Id);
this.Map(x => x.UserId);
this.Map(x => x.RoleId);
this.References(x => x.User)
.Not.LazyLoad()
.Not.Nullable()
.Cascade.SaveUpdate()
.Columns("applicationId", "userId");
this.References(x => x.Role)
.Not.LazyLoad()
.Not.Nullable()
.Cascade.SaveUpdate()
.Columns("applicationId", "roleId");
}
}
//FLUENT NHIBERNATE REPO
public class Repository<TIdentifier> : IRepository<TIdentifier> where TIdentifie : class, new()
{
...
//method used to search by criteria, in this particular case Item is type of User and it is used as criteria
public virtual IEnumerable<TIdentifier> LoadByCriteria(TIdentifier Item, int? RecordStartIndex = null, int? TotalRecords = null)
{
IList<Tidentifier> itemList;
using(ISession session = NHibernateConfiguration<TIdentifier>.OpenSession())
{
ICriteria criteria = session.CreateCriteria<TIdentifier>();
if(RecordStartIndex != null)
{
criteria.SetFirstResult((int)RecordStartIndex);
}
if(TotalRecords != null)
{
criteria.SetMaxResults((int)TotalRecords);
}
itemList = criteria.Add(Example.Create(Item))
.List<TIdentifier>();
}
if(itemList == null)
itemList = new List<TIdentifier>();
return itemList.ToList();
}
}
避免.Fetch.Join()
。它在 SQL 中创建连接,导致行的乘法。为避免 N+1 问题,请改用批量提取。
另请参阅:
- Criteria API: Fetch of a list returns repeated main entity
- Hibernate Subselect vs Batch Fetching