0

私は休閑中の実体を持っています:

人事会社

そして、PersonCompanyというエンティティがあります。これはPersonとCompanyの間に関係を作ります。

人のマッピングは次のとおりです。

public class PersonMap : SubclassMap<Person> {
    public PersonMap() {
        this.Table("Person");
        this.KeyColumn("Id");
        this.HasMany(x => x.PersonCompanys).AsSet().KeyColumn("PersonId").Fetch.Select().Inverse().Cascade.Delete();
    }
}

会社:

public class CompanyMap : SubclassMap<Company> {
    public CompanyMap() {
        this.Table("Company");
        this.KeyColumn("Id");
        this.HasMany(x => x.PersonCompanys).AsSet().KeyColumn("CompanyId").Fetch.Select().Inverse().Cascade.None();
    }
}

およびPersonCompany:

public class PersonCompanyMap : ClassMap<PersonCompany> {
    public PersonCompanyMap() {
        this.Table("PersonCompany");

        this.Version(x => x.ObjectVersion);
        this.Id(x => x.Id).GeneratedBy.Assigned();
        this.References(x => x.Company).Column("CompanyId").Fetch.Select();
        this.References(x => x.Person).Column("PersonId").Fetch.Select();
    }
}

SecondLevel-キャッシングは、一般的に、および規則のあるエンティティごとにアクティブ化されます。また、PersonCompanys-Collectionのキャッシング:

public class CachableConventions : IClassConvention, IHasManyConvention, IHasManyToManyConvention {
    private static readonly Type[] notCachableTypes = new[] {typeof(Word), typeof(ActivityWord), typeof(DbVersion), typeof(Deleted), typeof(ExchangeSyncState), typeof(Synchronizer), typeof(SerialletterField)};

    public void Apply(IClassInstance instance) {
        if (Array.IndexOf(notCachableTypes, instance.EntityType) >= 0) {
            return;
        }
        instance.Cache.ReadWrite();
    }

    public void Apply(IManyToManyCollectionInstance instance) {
        if (Array.IndexOf(notCachableTypes, instance.ChildType) >= 0) {
            return;
        }
        instance.Cache.ReadWrite();
    }
    public void Apply(IOneToManyCollectionInstance instance) {
        if (Array.IndexOf(notCachableTypes, instance.ChildType) >= 0) {
            return;
        }
        instance.Cache.ReadWrite();
    }
}

ここで、新しいPersonを作成し、新しいCompanyを保存した後、PersonCompany-RecordをPersonCompanies-Collectionに追加します。

作成したPersonを選択した後、PersonCompanys-Collectionは空になります。SecondLevel-Cachingなしで同じことを行うと、PersonCompanys-Collectionには作成されたエンティティが含まれます。

誰かが知っていますか、ここで何がうまくいかない可能性がありますか?

編集-追加情報:

この手順により、問題が発生します。

  1. で新しい人を作成するSession.Save(person)
  2. で人をロードしますperson = Session.Get(person.Id)
  3. を持つ人からpersonCompanyを取得しますpersonCompany = person.PersonCompany.FirstOrDefault()(これは空になります)
  4. 新しいPersonCompany-Entryを作成しますSession.Save(new PersonCompany(Guid.NewGuid()) {Person = person}))
  5. で人をロードしますperson = Session.Get(person.Id)
  6. ここでperson.PersonCompany、空のリストを返します。

手順3を実行しない場合、すべてが正常に機能しています。

4

1 に答える 1

0
  1. 上記を参照してください
  2. 上記を参照してください
  3. personCompany = person.PersonCompany.FirstOrDefault()を持つPersonからpersonCompanyを取得します(これは空になります)

    これにより、コレクションが空のコレクションに初期化されます

  4. Session.Save(new PersonCompany(Guid.NewGuid()){Person = person}))を使用して新しいPersonCompany-Entryを作成します

    データベースにPersonCompanyレコードを作成します

  5. person = Session.Get(person.Id)で人をロードします

    キャッシュされた人物オブジェクトを返すだけなので、これは基本的に「何もしない」です

  6. これで、person.PersonCompanyは空のリストを返します

コレクションはステップ3で空のコレクションに初期化されたため、それだけが返されます。nhibernateは、何かが変更されたかどうかを確認するために別のselectを発行しません。おそらくローカルの変更を破棄したり、競合を引き起こしたりして、あまり効率的ではない場合

行う

  • session.Clear();ステップ3bまたは
  • session.Refresh(person);ステップ5として

その後、期待どおりに機能しています

于 2012-09-14T11:06:00.270 に答える