我对通过NHibernate获得的异常感到困惑和沮丧.我为这篇文章的篇幅道歉,但我已经尝试包含一个适当的细节来解释这个问题,以获得一些帮助!
这是事实:
>我有一个Person类,它包含一个属性BillingManager,它也是一个Person类型.我把它映射为FNH“参考”.
>我有一个ExpenseReport类,它包含一个属性SubmittedBy,它是一个Person类型.我把它映射为FNH“参考”.
>我有一个BillableTime类,它包含一个属性Person,它是Person类型.我把它映射为FNH“参考”.
> Person包含ExpenseReport类型的集合(IList)(属性ExpenseReports)
> Person包含BilledTime类型的集合(IList)(属性Time)
(请参阅帖子底部的类和映射.)
一切都很酷,直到我添加了IList< BilledTime>时间收集到人.现在,当我尝试访问_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的引用,它完美地运行.
我能够弄清楚的一件事是,如果我从人物映射中删除BillingManager引用(引用(p => p.BillingManager)),则异常消失并且事情似乎有效(关于BillableTime;它是当然打破了BillingManager持久性).现在看来有一些“自引用”问题,因为Person.BillingManager属性本身就是对Person的引用.
知道这里发生了什么吗?我不知所措……
谢谢.
===课程&映射===
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; }
}
最佳答案 以下行应解决问题,但我不确切地知道它为什么会发生.如果我有空闲时间,我会调查.
HasMany(p => p.Time).Cascade.AllDeleteOrphan().KeyColumn("Person_Id");