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映射而不急于加载“用户”,则在尝试保存时会出现各种错误。然后请更正问题中的
设施一对多用户
设施多对多用户
。尽管如此,我发布的查询应该在急切获取时去掉双笛卡尔积,并且会稍微减轻痛苦。谢谢。它确实减轻了一点疼痛。回答得好。