2011-01-25 225 views
0

我试图包装遗留数据库(不是由我创建)NHibernate周围。它具有我可以最好地描述为“表格表”的名称,称为TABLE_DETAIL。它看起来像这样:表NHibernate映射表

COLUMN_NAME | TABLE_VALUE | TABLE_DESC 
-------------+-----------------+--------------------------------- 
state  | CA    | California 
state  | NY    | New York 
... 
country  | US    | United States 
country  | CA    | Canada 

我想映射这个使用流利NHibernate与表每类的层次结构战略。换句话说,我有一个TableDetail类,以及State和Country的子类。我使用COLUMN_NAME作为鉴别器。

TableDetailMap.cs:

public class TableDetailMap : ClassMap<TableDetail> 
{ 
    public TableDetailMap() 
    { 
    Table("TABLE_DETAIL"); 
    CompositeId() 
     .KeyProperty(x => x.TableValue, "TABLE_VALUE") 
     .KeyProperty(x => x.ColumnName, "COLUMN_NAME"); 
    Map(x => x.ColumnName).Column("COLUMN_NAME"); 
    Map(x => x.TableDesc).Column("TABLE_DESC"); 
    DiscriminateSubClassesOnColumn("COLUMN_NAME"); 
    } 
} 

StateMap.cs:因此

public class StateMap : SubclassMap<State> 
{ 
    public StateMap() 
    { 
    DiscriminatorValue("state"); 
    } 
} 

TABLE_DETAIL具有复合密钥(由COLUMN_NAME/TABLE_VALUE的),并且鉴别器是一个那些领域。我的问题是NHibernate期望组合键的两个组件在另一个表中被引用 - 但它们不应该是,因为一个是由鉴别器定义的。

例如,我有ADDRESS_RECORD表:

LINE_1   | CITY   | STATE | ZIP 
-----------------+-----------------+-----------+---------------- 
123 Any Street | Anytown  | CA  | 12345 

的问题出现时,我尝试了我的“国家”字段映射到我的状态类。 ADDRESS_RECORD中的STATE列引用TABLE_DETAIL主键的一半 - TABLE_VALUE部分。 COLUMN_NAME的部分是“国家” - 因为它是鉴别者,我期望它应该提供。但NHibernate的并不这么认为,并抛出该异常:

Foreign key (FK3D33E87CA66E339C:ADDRESS_RECORD [STATE])) must have same number of columns as the referenced primary key (TABLE_DETAIL [TABLE_VALUE, COLUMN_NAME]) 

我怎样才能映射这个让NHibernate的知道自动提供“状态”作为组合键下半年的价值?

如果我可以提供更多信息,请让我知道。

回答

0

我想出了一个如此修复。在基类图(TableDetailMap.cs),其中I指定的鉴别器,我指定“总是与值选择”,像这样:

public class TableDetailMap : ClassMap<TableDetail> 
{ 
    public TableDetailMap() 
    { 
    ...snip... 

    DiscriminateSubClassesOnColumn("COLUMN_NAME").AlwaysSelectWithValue(); 
    } 
} 

然后,在所有使用一个的映射类的TableDetail对象,我不得不指定使用“选择”进行读取时,就像这样:

public class AddressRecordMap : ClassMap<AddressRecord> 
{ 
    public AddressRecordMap() 
    { 
    ...snip... 

    References(x => x.State) 
     .Column("STATE") 
     .Fetch.Select(); 

    ...snip... 
    } 
} 

这还是在我作为一个复合ID的一部分,这些对象之一的情况下,没有工作。我不知道如何解决这个问题,但我现在能够解决它。