2012-04-18 72 views
0

我是一个试图进入nHibernate的新手,我有一段时间。我得到以下异常(和内部异常)nhibernate“异常发生的XYZ获取者”

异常发生Common32.ExtractionCompany.ID

对象的吸气不匹配目标类型。

基本上,因为我得到了入门,我有一些类应该有另一个类的实例存储在列表中。存储C的商店B's等。我使用GUID作为密钥,所以在Oracle 11g(我的数据库)中,我使用Raw(16)作为数据类型。奇怪的是,这部分工作。如果我把一些B对象放在A中,一切都很好。一旦我尝试将C对象放入B中,那么所有内容都会中断。

这是我的SQL来创建目标表。每个表都有一个ID列作为主键,而一列是外键返回到上一个表。

create table ExtractionCommand 
(ID Raw(16)); 

create table ExtractionCompany 
(ID Raw(16), 
CommandID Raw(16)); 

create table ExtractionTable 
(ID Raw(16), 
CompanyID Raw(16)); 

create table ExtractionColumn 
(ID Raw(16), 
TableID Raw(16)); 

create table ExtractionTarget 
(ID Raw(16), 
ColumnID Raw(16)); 

这是我的C#类。

[Serializable] 
public class ExtractionCommand 
{ 
    public virtual Guid ID { get; set; } 
    private IList<ExtractionCompany> m_company = new List<ExtractionCompany>(); 
    public virtual IList<ExtractionCompany> Company 
    { 
     get { return m_company; } 
     set { m_company = value; } 
    } 
} 

[Serializable] 
public class ExtractionCompany 
{ 
    public virtual Guid ID { get; set; } 
    public virtual Guid CommandID { get; set; } 
    private IList<ExtractionTable> m_tables = new List<ExtractionTable>(); 
    public virtual IList<ExtractionTable> Tables 
    { 
     get { return m_tables; } 
     set { m_tables = value; } 
    } 
} 

[Serializable] 
public class ExtractionTable 
{ 
    public virtual Guid ID { get; set; } 
    public virtual Guid CompanyID { get; set; } 
    private IList<ExtractionColumn> m_columns = new List<ExtractionColumn>(); 
    public virtual IList<ExtractionColumn> Columns 
    { 
     get { return m_columns; } 
     set { m_columns = value; } 
    } 
} 

[Serializable] 
public class ExtractionColumn 
{ 
    public virtual Guid ID { get; set; } 
    public virtual Guid TableID { get; set; } 
    public virtual ExtractionTarget Target { get; set; } 
} 

[Serializable] 
public class ExtractionTarget 
{ 
    public virtual Guid ID { get; set; } 
    public virtual Guid ColumnID { get; set; } 
    public virtual string TargetTable { get; set; } 
    public virtual string TargetColumn { get; set; } 
} 

这是调用保存到数据库(Oracle 11g)的C#代码。

ExtractionCommand cmd = new ExtractionCommand(); 
cmd.ID = Guid.NewGuid(); 

ExtractionCompany c1 = new ExtractionCompany();      
cmd.Company.Add(c1); 

ExtractionTable t1 = new ExtractionTable(); 
c1.Tables.Add(t1); 

session.Save(cmd); 
transaction.Commit(); 

我的映射

<class name="ExtractionCommand" table="ExtractionCommand" > 
<id name="ID"> 
    <generator class="guid" /> 
</id>  
<bag name="Company" cascade="all"> 
    <key column="CommandID" /> 
    <one-to-many class="ExtractionCompany"/> 
</bag> 
</class> 

<class name="ExtractionCompany" table="ExtractionCompany" > 
<id name="ID"> 
    <generator class="guid" /> 
</id> 
<property name="CommandID"/>  
<bag name="Tables" cascade="all"> 
    <key column="CompanyID" /> 
    <one-to-many class="ExtractionCompany"/> 
</bag> 
</class> 

<class name="ExtractionTable" table="ExtractionTable" > 
<id name="ID"> 
    <generator class="guid" /> 
</id> 
<property name="CompanyID"/> 
<bag name="Columns" cascade="all"> 
    <key column="TableID"/> 
    <one-to-many class="ExtractionColumn"/> 
</bag> 
</class> 

<class name="ExtractionColumn" table="ExtractionColumn" > 
<id name="ID"> 
    <generator class="guid" /> 
</id> 
<property name="TableID" /> 
<one-to-one name="Target" class="ExtractionTarget"/> 
</class> 

<class name="ExtractionTarget" table="ExtractionTarget" > 
<id name="ID"> 
    <generator class="guid" /> 
</id> 
<property name="TargetTable"/> 
<property name="TargetColumn"/> 
</class> 

任何帮助是极大的赞赏。谢谢。 mj

回答

2

它因为在ExtractionCompany映射的one-to-many部分中使用了错误的类型而中断。您需要使用ExtractionTable代替:

<class name="ExtractionCompany" table="ExtractionCompany" > 
<id name="ID"> 
    <generator class="guid" /> 
</id> 
<property name="CommandID"/>  
<bag name="Tables" cascade="all"> 
    <key column="CompanyID" /> 
    <one-to-many class="ExtractionTable"/> 
</bag> 
</class> 

此外:

你的类不应该包含父的ID。如果他们确实需要对父级的引用,请添加具有父级类型的属性并将其映射为引用。

+1

好点。我也会提到一般你不应该序列化你的nhibernate实体。如果你使用延迟加载,这是行不通的。通常我认为这里接受的解决方案是使用Dtos。 – 2012-04-18 15:03:53

+0

先生们,谢谢,谢谢,谢谢! – 2012-04-18 15:07:18