查询时,NHibernate HasMany列表仍为空

时间:2013-05-23 08:58:48

标签: nhibernate fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping hibernate-onetomany

我遇到了一个奇怪的问题:每当我查询一个有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>

希望有人可以为此带来一些启示......先谢谢!

此致 马丁

1 个答案:

答案 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。