【发布时间】:2012-09-06 20:29:39
【问题描述】:
我有闲散的实体:
人 公司
然后,有一个实体 PersonCompany,它在 Person 和 Company 之间建立关系
Person 的映射是:
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();
}
}
和个人公司:
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-Caching 被激活一般并且对于每个具有约定的实体。还有 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 包含创建的实体。
有人知道,这里出了什么问题吗?
编辑 - 附加信息:
这是导致问题的步骤:
- 使用
Session.Save(person)创建一个新人 - 用
person = Session.Get(person.Id)加载人 - 从具有
personCompany = person.PersonCompany.FirstOrDefault()的人那里获取personCompany(这将为空) - 使用
Session.Save(new PersonCompany(Guid.NewGuid()) {Person = person}))创建一个新的 PersonCompany-Entry - 用
person = Session.Get(person.Id)加载人 - 现在,
person.PersonCompany返回一个空列表。
当我不执行第 3 步时,一切正常。
【问题讨论】:
-
我的直觉是这与您的缓存几乎没有关系。在创建 Person、Company 和 PersonCompany 对象期间,如果没有看到您在做什么,我无能为力。
-
当我停用二级缓存时,它工作正常。也许问题是我如何将 Person 与新的 PersonCompany 关联起来。我做 personCompany.Person = person 并调用 Session.Insert(personCompany)
-
首先,除非您有充分的理由使用 Session.Insert,否则您应该使用 Session.SaveOrUpdate(...)。如果我没记错的话,Session.Insert 避免了很多内部缓存。
-
对不起——我的工厂方法是插入,它调用 Session.Save() 来创建新的 PersonCompany——在它为这个人调用 Session.Merge(person) 之前(这个人不是新的) .这是两个不同的会话。
-
在这种情况下,听起来这两个会话没有同步它们的缓存。不幸的是,这可能超出了我的专业范围。您可以尝试的一件事是确保您的会话打开和关闭正在排队。打开会话 1,创建人员 1,关闭会话 1,打开会话 2,创建公司 1,关闭会话 2,打开会话 3,创建 PersonCompany(并将人员 1 和公司 1 关联到它),关闭会话 3,打开会话 4,选择 Person 1(应该有正确的关联 PersonCompany),关闭会话 4。
标签: c# nhibernate fluent-nhibernate second-level-cache