我遇到了一个奇怪的问题:每当我查询一个有IList的实体时,它仍然是空的。查询语言实体本身是可能的......这与我的复合键有关吗?
NHProf显示sql查询BOTH实体,但由于某种原因,结果没有链接: - /
以下是一些代码:
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!我确保数据在数据库中。因为我使用流利,我也检查了创建的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>
希望有人可以为此带来一些启示......先谢谢!
此致 马丁
答案 0 :(得分:0)
这是一个有趣的,我在所有项目中使用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。