0

テーブル構造に多対多のマッピングがあり、単純なレコードを編集しようとすると頭痛の種になるという問題があります。

問題が発生している場所のレイアウト例:

Facilities Many-to-One Locations
Facilities One-to-Many Users
Users Many-to-Many Locations
Users One-to-Many PreviousPasswords

施設レコードを変更すると (名前フィールドを変更)、保存時に次のエラーが表示されます。

コレクション [Users.PreviousPasswords] は flush() によって処理されませんでした

マッピングは次のようになります。

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");
}

施設レコードを正常に更新できる唯一の方法は、レコードを変更して保存する前に、次の関数を使用してレコードを取得することです。

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>();
}

この方法の問題点は、10,000 人のユーザーがいる場合、このクエリの処理に時間がかかることです。さらに悪いことに、場所も 100 ある場合、1 つの施設レコードを編集するのに約 2 分かかります。

マッピングに何らかの問題があると確信しています。修正方法も、どこから始めればよいかもわかりません。これについての助けをいただければ幸いです。前もって感謝します。

4

1 に答える 1

0

施設のすべてのユーザーが本当に必要ですか? 使用できるユーザーのみを追加する場合

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;
}
于 2013-01-08T08:12:49.737 に答える