我們有一個我們無法更改的遺留數據庫。我們正在嘗試移植到NHibernate,而不是舊的DataAccess層,這是一個垃圾,而且太慢了。將NHibernate導航器映射到組合鍵問題的一部分 - 遺留數據庫的使用
它具有這樣的表:
GPI表具有(PU_ID,PAR_ID,數據,數據2)個列
BLOCK表具有(GA_ID,數據PAR_ID)列
COMPANY表具有(PU_ID,數據)列
我創造了這些映射爲上面的表:
GPI
<class name="GroupPartnerInterest" table="[GPI]">
<composite-id >
<key-property name="GroupId" column="PAR_ID" />
<key-property name="CompanyId" column="PU_ID" />
</composite-id>
<property name="data" column="Data"/>
<property name="data2" column="Data2"/>
<many-to-one name="Company" fetch="select" cascade="none">
<column name="PU_ID"/>
</many-to-one>
<set name="Blocks" cascade="none" inverse="true" fetch="select">
<key property-ref="GroupId">
<column name="PAR_ID"/>
</key>
<one-to-many class="Block"/>
</set>
</class>
BLOCK
<class name="Block" table="[BLOCK]" >
<id name="BlockId" column="GA_ID" >
<generator class="assigned"/>
</id>
<property name="data" column="Data"/>
<property name="GroupId" column="PAR_ID"/>
<set name="GroupPartnerInterests" cascade="all-delete-orphan" fetch="select">
<key property-ref="GroupId">
<column name="PAR_ID"/>
</key>
<one-to-many class="GroupPartnerInterest"/>
</set>
</class>
公司
<class name="Company" table="[COMPANY]">
<id name="CompanyId" column="PU_ID">
<generator class="assigned"/>
</id>
<property name="data" column="Data"/>
<set name="GroupPartnerInterests" cascade="none" inverse="true" fetch="select">
<key>
<column name="PU_ID"/>
</key>
<one-to-many class="GroupPartnerInterest"/>
</set>
</class>
的類是非常簡單樸素。全部實現Equals和GetHashCode方法。
這裏是工作的航海家列表:
- GroupPartnerInterest.Company - 偉大工程
- Company.GroupPartnerInterests - 偉大工程
- GroupPartnerInterest.Company - 偉大工程
而且這兩個失敗:
-
個
- Block.GroupPartnerInterests:
我有一個單元測試:
[TestMethod]
public void TestGroupPartnerInterests()
{
using (ISession session = SessionFactory.OpenSession())
{
IList<Block> blocks = session.CreateCriteria(typeof(Block))
.SetMaxResults(5).List<Block>();
foreach (var block in blocks)
{
TestContext.WriteLine("Block #{0}", block.BlockId);
if (block.GroupPartnerInterests != null)
{
foreach (GroupPartnerInterest gpi in block.GroupPartnerInterests)
{
TestContext.WriteLine("Company '{0}':", gpi.Company.CompanyId);
}
}
}
}
}
如果我註釋掉GPI映射測試工作模塊的導航地圖和輸出一些數據:
Block #1
Company 'LALA':
Company 'LALA SA':
Block #2
Company 'BG PO':
Company 'LIMPOPO':
Block #3
Company 'HAHA':
Company 'Other partner(s)':
Block #4
但測試失敗,出現以下錯誤:
NHibernate.LazyInitializationException: Initializing[Model.EntityClasses.Block#999]-failed to lazily initialize a collection of role: Model.EntityClasses.Block.GroupPartnerInterests, no session or session was closed.
'999'是現有的PAR_ID - 數據是一致的:在GPI中有兩個包含此PAR_ID和幾條記錄的塊。
爲什麼它在某個時候關閉會話?
- GroupPartnerInterest.Blocks:
單元測試是如我上面提到的,只是不同的屬性用於幾乎相同。下面 錯誤是:
NHibernate.MappingException: NHibernate.MappingException: property not found: GroupId on entity Model.EntityClasses.GroupPartnerInterest.
如果我刪除「屬性-REF = GroupId的」從塊導航在GPI映射元素,我會出現以下情況例外:
NHibernate.FKUnmatchingColumnsException: NHibernate.FKUnmatchingColumnsException: Foreign key (FKA3966498349694F:[BLOCK] [PAR_ID])) must have same number of columns as the referenced primary key ([GPI] [PAR_ID, PU_ID]).
是有沒有辦法將Blocks映射到GPI,這樣GroupPartnerInterest.Blocks導航器就可以工作了?
謝謝, 亞歷克斯
謝謝您的深入解答! 我將嘗試說服我們的團隊領導改變數據庫架構,只需添加一個自動生成(增量)主鍵到GPI表。 這將修復property-ref = GroupId問題,並應修復我的問題導航屬性 – LucID 2010-08-27 09:24:33
我有一個非常類似的問題。我試圖用xml和流利的映射來映射這個場景,但沒有喜悅。不幸的是,我現在無法改變模式。我可以讓你看看嗎? http://stackoverflow.com/questions/25191275/fluent-nhibernate-map-hasmany-to-entity-table-with-no-primary-key – 2014-08-08 15:09:35