查询时 NHibernate HasMany List 保持为空
Posted
技术标签:
【中文标题】查询时 NHibernate HasMany List 保持为空【英文标题】:NHibernate HasMany List remains empty when querying 【发布时间】:2013-05-23 08:58:48 【问题描述】:我遇到了一个奇怪的问题:每当我查询具有 IList 的实体时,它仍然是空的。可以查询语言实体本身...这与我的复合键有关吗?
NHProf 显示 BOTH 实体都被 sql 查询了,但是由于某种原因,结果没有链接:-/
这里有一些代码:
public class Employee : User
public virtual string firstname get; set;
public virtual string lastname get; set;
public virtual string uid get; set;
public virtual string identity_provider
public virtual IList<Language> languages get; set;
对应的映射:
public class EmployeeMap : ClassMap<Employee>
public EmployeeMap()
Table("employee");
Not.LazyLoad();
CompositeId()
.KeyProperty(x => x.uid)
.KeyProperty(x => x.identity_provider);
Map(x => x.firstname);
Map(x => x.lastname);
HasMany<Language>(x => x.languages)
.Table("employee_spoken_language")
.KeyColumns.Add("employee_uid","employee_identity_provider")
.Inverse().Cascade.All();
为了完整起见,这就是“语言”的映射方式:
public class LanguageMap : ClassMap<SpokenLanguage>
public LanguageMap()
Table("employee_spoken_language");
Not.LazyLoad();
CompositeId()
.KeyProperty(x => x.employee_uid)
.KeyProperty(x => x.employee_identity_provider)
.KeyProperty(x => x.name);
References(x => x.knowledge_level).Column("knowledge_level");
无论我更改什么,我的员工实体总是显示language =
!?这真的让我发疯,我找不到错误。我确保执行查询语言的 sql!我确保数据在数据库中。而且因为我使用的是fluent,所以我还检查了创建的hmb:
<bag cascade="all" inverse="true" name="languages" table="employee_spoken_language">
<key>
<column name="employee_uid" />
<column name="employee_identity_provider" />
</key>
<one-to-many class="Jobportal.Language, wcf, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>
希望有人能对此有所启发...提前致谢!
问候, 马丁
【问题讨论】:
好的...现场测试:我重新创建了两个类并将仅 uid 设置为 id。相同的映射...有效。如果我重新应用复合键,它会按照描述失败。很奇怪... :-/ Martin 在我的回答中为你做了映射 【参考方案1】:这是一个有趣的项目,我在所有项目中都使用 nHibernate,但很少使用复合键。我曾经手动完成所有映射(学习),但现在我使用 Entity Developer 工具来生成它们。我在我的数据库中创建了与您的结构相同的可比较的 Employee 和 Language 表,并在它们上运行 Entity Developer 以为您生成流畅的映射。我在下面列出了这些。我没有看到任何巨大的差异,但知道 nHibernate 有多么挑剔可能值得一试。我可能有一些属性长度错误等,但会根据您的特定需求进行调整。
对于员工:
public class EmployeeMap : ClassMap<Employee>
public EmployeeMap()
Schema(@"dbo");
Table(@"Employees");
LazyLoad();
CompositeId()
.KeyProperty(x => x.Uid, set =>
set.Type("String");
set.ColumnName("uid");
set.Length(50);
set.Access.Property(); )
.KeyProperty(x => x.IdentityProvider, set =>
set.Type("String");
set.ColumnName("identity_provider");
set.Length(50);
set.Access.Property(); );
Map(x => x.Firstname)
.Column("firstname")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Not.Nullable();
Map(x => x.Lastname)
.Column("lastname")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Not.Nullable();
HasMany<Language>(x => x.Languages)
.Access.Property()
.AsSet()
.Cascade.None()
.LazyLoad()
.Inverse()
.Generic()
.KeyColumns.Add("uid", mapping => mapping.Name("uid")
.SqlType("varchar")
.Not.Nullable()
.Length(50))
.KeyColumns.Add("identity_provider", mapping => mapping.Name("identity_provider")
.SqlType("varchar")
.Not.Nullable()
.Length(50));
语言:
public class LanguageMap : ClassMap<Language>
public LanguageMap()
Schema(@"dbo");
Table(@"Languages");
LazyLoad();
CompositeId()
.KeyProperty(x => x.Uid, set =>
set.Type("String");
set.ColumnName("uid");
set.Length(50);
set.Access.Property(); )
.KeyProperty(x => x.IdentityProvider, set =>
set.Type("String");
set.ColumnName("identity_provider");
set.Length(50);
set.Access.Property(); )
.KeyProperty(x => x.Name, set =>
set.Type("String");
set.ColumnName("name");
set.Length(50);
set.Access.Property(); );
References(x => x.Employee)
.Class<Employee>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.Columns("uid", "identity_provider");
如果这些工作更好,请告诉我,如果没有,我会生成一些测试数据并尝试使用映射对这些表运行一些查询。
要考虑的另一件事是确保您使用的是最新版本的 nHibernate。
【讨论】:
嘿!感谢您的提示。由于我在这个项目中的时间不多了,我将 uid 和身份提供者连接起来以将其用作单个字段并避免 90% 的复合键。但是,一旦我“在安全方面”,我会尝试你的方法并在这里发布反馈。可能需要几个星期。问候,以上是关于查询时 NHibernate HasMany List 保持为空的主要内容,如果未能解决你的问题,请参考以下文章
流畅的 NHibernate HASMANY 映射,无需参考
使用 Fluent NHibernate 和 AsList() 时指定主键
如何在Fluent NHibernate中映射受保护的集合?