NHibernate异常:无法初始化集合,无效的列名称。流畅的映射。也许是多对一的问题?

时间:2011-10-07 00:20:59

标签: fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping

我对通过NHibernate获得的异常感到困惑和沮丧。我为这篇文章的篇幅道歉,但我试图包含一个适当的细节来解释这个问题,以便得到一些帮助!

以下是事实:

  • 我有一个Person类,其中包含属性BillingManager,它也是Person类型。我把它映射为FNH“参考”。
  • 我有一个ExpenseReport类,其中包含属性SubmittedBy,这是Person类型。我把它映射为FNH“参考”。
  • 我有一个BillableTime类,其中包含属性Person,这是Person类型。我把它映射为FNH“参考”。
  • Person包含ExpenseReport类型的集合(IList)(属性ExpenseReports
  • Person包含BilledTime类型的集合(IList)(属性Time

(请参阅帖子底部的类和映射。)

在我将IList<BilledTime> Time集合添加到Person之前,一切都很酷。现在,当我尝试访问_person.Time时,我得到一个例外:

代码:

// Get billable hours
if (_person.Time == null || 
    _person.Time.Count(x => x.Project.ProjectId == project.ProjectId) == 0)
{
    // No billable time for this project
    billableHours = Enumerable.Repeat(0F, 14).ToArray();
}

例外:

could not initialize a collection: 
[MyApp.Business.Person.Time#211d3567-6e20-4220-a15c-74f8784fe47a]
[SQL: SELECT 
time0_.BillingManager_id as BillingM8_1_, 
time0_.Id as Id1_, 
time0_.Id as Id1_0_, 
time0_.ReadOnly as ReadOnly1_0_, 
time0_.DailyHours as DailyHours1_0_, 
time0_.Week_id as Week4_1_0_, 
time0_.Person_id as Person5_1_0_, 
time0_.Project_id as Project6_1_0_, 
time0_.Invoice_id as Invoice7_1_0_ 
FROM [BillableTime] time0_ 
WHERE time0_.BillingManager_id=?]

BillingManager_id确实是一个无效的列名,它在BillableTime表中不存在。但是,我不明白为什么NHB创建了这个SQL ...对我来说没有意义。在搜索解决方案时,我已经看到了很多“无效的列名称”异常,但似乎没有任何效果。更令人困惑的是:与BilledTime类似,ExpenseReport类型也包含对Person的引用,并且效果非常好。

我能弄清楚的一件事是,如果我从Person映射(References(p => p.BillingManager))中删除BillingManager引用,则异常消失并且事情似乎有效(关于BillableTime;它当然会中断BillingManager持久性)。现在似乎存在一些“自我引用”问题,因为Person.BillingManager属性本身就是对Person的引用。

知道这里发生了什么吗?我不知所措......

感谢。

===课程&amp;映射===

public class Person
{
    public virtual string LastName { get; set; }
    public virtual string FirstName { get; set; }

    public virtual Person BillingManager { get; set; }

    public virtual IList<ExpenseReport> ExpenseReports { get; set; }
    public virtual IList<BillableTime> Time { get; set; }
}


public class PersonMapping : ClassMap<Person> 
{        
    public PersonMapping()
    {
        Id(p => p.UserId).GeneratedBy.Assigned();
        Map(p => p.LastName).Not.Nullable();
        Map(p => p.FirstName).Not.Nullable();

        References(p => p.BillingManager);

        HasMany(p => p.ExpenseReports).Cascade.AllDeleteOrphan();
        HasMany(p => p.Time).Cascade.AllDeleteOrphan(); 
    }
}

public class BillableTime
{
    public virtual int Id { get; private set; }
    public virtual Week Week { get; set; }
    public virtual Person Person { get; set; }
    public virtual Project Project { get; set; }
    public virtual float[] DailyHours { get; set; }
    public virtual Invoice Invoice { get; set; }
    public virtual bool ReadOnly { get; set; }
}       

public class BillableTimeMapping : ClassMap<BillableTime>
{
    public BillableTimeMapping()
    {
        Id(x => x.Id);
        References(x => x.Week);
        References(x => x.Person);
        References(x => x.Project);
        References(x => x.Invoice);
        Map(x => x.ReadOnly).Not.Nullable().Default("0");
        Map(x => x.DailyHours).Length(28);  
    }
}


public class ExpenseReport
{
    public virtual long Id { get; set; }        
    public virtual Person SubmittedBy { get; set; }             
}

1 个答案:

答案 0 :(得分:2)

以下一行应解决问题,但我不确切地知道它为什么会发生。如果我有空闲时间,我会调查。

HasMany(p => p.Time).Cascade.AllDeleteOrphan().KeyColumn("Person_Id");