Fluent nhibernate 通过多对多映射更新记录的问题
我有一个问题,在我的表结构中有一个多对多映射,在试图编辑一个简单记录时,这会造成麻烦 我遇到问题的布局示例:Fluent nhibernate 通过多对多映射更新记录的问题,fluent-nhibernate,fluent-nhibernate-mapping,Fluent Nhibernate,Fluent Nhibernate Mapping,我有一个问题,在我的表结构中有一个多对多映射,在试图编辑一个简单记录时,这会造成麻烦 我遇到问题的布局示例: Facilities Many-to-One Locations Facilities One-to-Many Users Users Many-to-Many Locations Users One-to-Many PreviousPasswords 如果更改设施记录(更改名称字段),则在保存时会出现以下错误: flush()未处理集合[Users.PreviousPasswords
Facilities Many-to-One Locations
Facilities One-to-Many Users
Users Many-to-Many Locations
Users One-to-Many PreviousPasswords
如果更改设施记录(更改名称字段),则在保存时会出现以下错误:
flush()未处理集合[Users.PreviousPasswords]
映射看起来像:
public FacilitiesMap()
{
Table("Facilities");
Id(x => x.ID);
Map(x => x.Name);
HasMany(x => x.Users).KeyColumn("FacilitiesID").Cascade.AllDeleteOrphan().Inverse();
HasMany(x => x.Locations).KeyColumn("FacilitiesID").Cascade.AllDeleteOrphan().Inverse();
}
public UsersMap()
{
Table("Users");
Id(x => x.ID);
Map(x => x.FirstName);
Map(x => x.LastName);
References(x => x.Facilities, "FacilitiesID").ForeignKey("ID");
HasMany(x => x.PreviousPasswords).KeyColumn("UsersID").Cascade.AllDeleteOrphan().Inverse();
HasManyToMany<Locations>(x => x.Locations)
.Schema("Members")
.Table("UsersToLocations")
.ParentKeyColumn("UsersID")
.ChildKeyColumn("LocationsID")
.LazyLoad()
.Cascade.SaveUpdate().Inverse();
}
public LocationsMap()
{
Table("Locations");
Id(x => x.ID);
Map(x => x.Name);
References(x => x.Facilities, "FacilitiesID").ForeignKey("ID");
HasMany(x => x.Patients).KeyColumn("LocationsID").Cascade.AllDeleteOrphan().Inverse();
HasManyToMany<Users>(x => x.Users)
.Schema("Members")
.Table("UsersToLocations")
.ParentKeyColumn("LocationsID")
.ChildKeyColumn("UsersID")
.Cascade.SaveUpdate();
}
public PreviousPasswordsMap()
{
Table("PreviousPasswords");
Id(x => x.ID);
Map(x => x.Password);
Map(x => x.DateTime);
References(x => x.Users, "UsersID").ForeignKey("ID");
}
公共设施地图()
{
表(“贷款”);
Id(x=>x.Id);
Map(x=>x.Name);
HasMany(x=>x.Users).KeyColumn(“FacilitiesID”).Cascade.AllDeleteOrphan().Inverse();
HasMany(x=>x.Locations).KeyColumn(“FacilitiesID”).Cascade.AllDeleteOrphan().Inverse();
}
公共用户smap()
{
表(“用户”);
Id(x=>x.Id);
Map(x=>x.FirstName);
Map(x=>x.LastName);
参考文件(x=>x.设施,“设施ID”).外键(“ID”);
HasMany(x=>x.PreviousPasswords).KeyColumn(“UsersID”).Cascade.AllDeleteOrphan().Inverse();
HasManyToMany(x=>x.Locations)
.Schema(“成员”)
.表格(“用户位置”)
.ParentKeyColumn(“UsersID”)
.ChildKeyColumn(“位置SID”)
.LazyLoad()
.Cascade.SaveUpdate().Inverse();
}
公共场所地图()
{
表(“位置”);
Id(x=>x.Id);
Map(x=>x.Name);
参考文件(x=>x.设施,“设施ID”).外键(“ID”);
HasMany(x=>x.Patients).KeyColumn(“LocationsID”).Cascade.AllDeleteOrphan().Inverse();
HasManyToMany(x=>x.Users)
.Schema(“成员”)
.表格(“用户位置”)
.ParentKeyColumn(“LocationsID”)
.ChildKeyColumn(“UsersID”)
.Cascade.SaveUpdate();
}
公共密码
{
表(“以前的密码”);
Id(x=>x.Id);
映射(x=>x.Password);
Map(x=>x.DateTime);
引用(x=>x.Users,“UsersID”).ForeignKey(“ID”);
}
成功更新设施记录的唯一方法是,在更改和保存记录之前,使用以下功能获取记录:
public Facilities GetFacility(int id)
{
return FluentSessionManager.GetSession()
.CreateCriteria<Facilities>()
.Add(Expression.Eq("ID", id))
.SetFetchMode("Users", FetchMode.Eager)
.SetFetchMode("Locations", FetchMode.Eager)
.UniqueResult<Facilities>();
}
公共设施GetFacility(int-id)
{
return FluentSessionManager.GetSession()
.CreateCriteria()
.Add(表达式.Eq(“ID”,ID))
.SetFetchMode(“用户”,FetchMode.Eager)
.SetFetchMode(“位置”,FetchMode.Eager)
.UniqueResult();
}
此方法的问题是,如果有10000个用户,则处理此查询需要很长时间。甚至更糟糕的是,如果我们也有100个位置,那么需要大约2分钟才能获得要编辑的one Facilities记录
我确信在映射中存在某种问题。不知道如何修复,甚至不知道从哪里开始。在此方面的任何帮助都将不胜感激。
提前感谢。您真的需要该设施的所有用户吗?当您仅添加用户时,您可以使用
HasMany(x => x.Users).ExtraLazyLoad();
并在需要所有子集合时改进查询
public Facilities GetFacility(int id)
{
var session = FluentSessionManager.GetSession();
// ignore the result, we only want to cache the results in the session
session.CreateCriteria<Facilities>()
.Add(Expression.Eq("ID", id))
.SetFetchMode("Users", FetchMode.Eager)
.Future<Facilities>();
return session.CreateCriteria<Facilities>()
.Add(Expression.Eq("ID", id))
.SetFetchMode("Locations", FetchMode.Eager)
.FutureValue<Facilities>().Value;
}
公共设施GetFacility(int-id)
{
var session=FluentSessionManager.GetSession();
//忽略结果,我们只想在会话中缓存结果
session.CreateCriteria()
.Add(表达式.Eq(“ID”,ID))
.SetFetchMode(“用户”,FetchMode.Eager)
.Future();
返回会话。CreateCriteria()
.Add(表达式.Eq(“ID”,ID))
.SetFetchMode(“位置”,FetchMode.Eager)
.FutureValue().Value;
}
ExtraLazyLoad()是最新nHibernate版本中的新函数吗?由于某些原因,我在使用的版本中没有将其作为选项。谢谢。我下载了最新版本,现在有了映射的“ExtraLazyLoad()”命令。您的解决方案有问题。。。用户映射为HasManyToMany而不是HasMany。我从来没有遇到过HasMany或引用映射的问题。就在最近,我开始使用HasManyToMany,它会引起各种各样的胃灼热。事实证明,如果由于HasManyToMany映射而不急于加载“用户”,则在尝试保存时会出现各种错误。然后请更正问题中的设施一对多用户
到设施多对多用户
。尽管如此,我发布的查询应该在急切获取时去掉双笛卡尔积,并且会稍微减轻痛苦。谢谢。它确实减轻了一点疼痛。回答得好。