2010-02-23 69 views
2

我想引用一些子實體與部分父母組合鍵不是全部,爲什麼我不能?當我使用下面的映射而不是被評論的時候,會發生這種情況。爲什麼我不能引用子實體與部分父實體組合鍵

我收到以下錯誤

外鍵 VolatileEventContent必須有相同的 列數在表中引用 主鍵 LocationSearchView

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="JeanieMaster.Domain.Entities" assembly="JeanieMaster.Domain"> 
    <class name="LocationSearchView" table="LocationSearchView"> 

    <composite-id> 
     <key-property name="LocationId" type="Int32"></key-property> 
     <key-property name="ContentProviderId" type="Int32"></key-property> 
     <key-property name="CategoryId" type="Int32"></key-property> 
    </composite-id> 

    <property name="CompanyName" type="String" not-null="true" update="false" insert="false"/> 
    <property name="Description" type="String" not-null="true" update="false" insert="false"/> 
    <property name="CategoryId" type="Int32" not-null="true" update="false" insert="false"/> 
    <property name="ContentProviderId" type="Int32" not-null="true" update="false" insert="false"/> 
    <property name="LocationId" type="Int32" not-null="true" update="false" insert="false"/> 
    <property name="Latitude" type="Double" update="false" insert="false" /> 
    <property name="Longitude" type="Double" update="false" insert="false" /> 

    <bag name="Events" table="VolatileEventContent" where="DeactivatedOn IS NULL" order-by="StartDate DESC" lazy="false" cascade="none"> 
     <key> 
     <column name="LocationId"></column> 
     <column name="ContentProviderId"></column> 
     <!--<column name="LocationId"></column> 
     <column name="ContentProviderId"></column> 
     <column name="CategoryId"></column>--> 
     </key> 
     <one-to-many class="Event" column="VolatileEventContentId"></one-to-many> 
    </bag> 

    </class> 
</hibernate-mapping> 

而且VolatileEventContent映射文件

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="JeanieMaster.Domain.Entities" assembly="JeanieMaster.Domain"> 
    <class name="Event" table="VolatileEventContent" select-before-update="false" optimistic-lock="none"> 
    <composite-id> 
     <key-property name="LocationId" type="Int32"></key-property> 
     <key-property name="ContentProviderId" type="Int32"></key-property> 
    </composite-id> 

    <property name="Description" type="String" not-null="true" update="false" insert="false"/> 

    <property name="StartDate" type="DateTime" not-null="true" update="false" insert="false" /> 
    <property name="EndDate" type="DateTime" not-null="true" update="false" insert="false" /> 

    <property name="CreatedOn" type="DateTime" not-null="true" update="false" insert="false" /> 
    <property name="ModifiedOn" type="DateTime" not-null="false" update="false" insert="false" /> 

    <many-to-one name="Location" class="Location" column="LocationId" /> 

    <bag name="Artistes" table="EventArtiste" lazy="false" cascade="none"> 
     <key name="VolatileEventContentId" /> 
     <many-to-many class="Artiste" column="ArtisteId" ></many-to-many> 
    </bag> 
    </class> 
</hibernate-mapping> 
+0

你可以發佈'VolatileEventContent'的映射嗎? – 2010-02-23 13:42:46

+0

添加了附加映射 – 2010-02-23 13:53:18

回答

2

錯誤是正確的。我猜你正在使用SchemaExport來生成基於NHibernate映射的表,因爲你收到的錯誤聽起來像是在創建表和外鍵期間發生的。 SchemaExport會產生類似如下表(請注意散落在代碼的解釋):

CREATE TABLE LocationSearchView (
    LocationId int NOT NULL, 
    ContentProviderId int NOT NULL, 
    CategoryId int NOT NULL, 

    /* ...other columns... */ 

    /* Note: Generated from LocationSearchView's "composite-id" element. */ 
    PRIMARY KEY (LocationId, ContentProviderId, CategoryId) 
); 

/* Note: Table for the "Event" class. */ 
CREATE TABLE VolatileEventContent (
    LocationId int NOT NULL, 
    ContentProviderId int NOT NULL, 

    /* ...other columns... */ 

    /* Note: Generated from Event's "composite-id" element. */ 
    PRIMARY KEY (LocationId, ContentProviderId), 
    /* Note: Generated from the "key" element of LocationSearchView's Events bag. */ 
    FOREIGN KEY (LocationId, ContentProviderId) REFERENCES LocationSearchView (LocationId, ContentProviderId) 
); 

...因此錯誤。外鍵必須指向完整的主鍵或唯一鍵 - 不僅僅是主鍵的一部分。整個關鍵是3列,而不是2.爲什麼NHibernate將這些列用於外鍵?由於<key>元素的LocationSearchViewEvents包。 <key>指定來自哪些列指向。我們來考慮當你(或NHibernate)試圖從這些表中選擇時會發生什麼。假設以下數據:

 
TABLE LocationSearchView 
LocationId ContentProviderId CategoryId 
========== ================= ========== 
1   3     5 
1   3     6 
1   4     5 
1   4     6 
2   3     5 
2   3     6 
2   4     5 
2   4     6 
 
TABLE VolatileEventContent 
LocationId ContentProviderId 
========== ================= 
1   3 
1   4 
2   3 
2   4 

這是不可能的「一」 LocationSearchView有「許多」 Event秒。相反,它應該是相反的。鑑於這些表格,從EventLocationSearchView之間確實存在一對多的關係。

我不知道這個問題的正確解決方案是什麼,因爲我不知道你在努力完成什麼,但希望這有助於說明究竟是什麼問題。

+0

感謝您的響應Daniel的hbm文件代表我的表,我沒有使用SchemaExport(無論那是什麼),它是事件與LocationSearchView的關係I – 2010-03-20 16:15:34

+0

SchemaExport是一個基於你的NHibernate映射生成表的工具,我假設你正在使用它,因爲「外鍵......必須有相同數量的列......」聽起來像是一個錯誤創建表和外鍵可以提供這個錯誤的堆棧跟蹤嗎?我對你的表結構的猜測是不正確的嗎?我會更新我的答案以解釋爲什麼我認爲你的表看起來像這樣。 – 2010-03-21 01:24:07

0

我從來沒有使用nhibernate,但我猜測映射是非常類似休眠的。

如果您不希望一對多(LocationSearchView到很多VolatileEventContent)關聯使用LocationSearchView id,則需要在包的關鍵元素上定義將定義的屬性「property-ref」物業改用:

<bag name="Events" table="VolatileEventContent" ...> 
    <key property-ref="partialId"> 
    <column name="LocationId"></column> 
    <column name="ContentProviderId"></column> 
    </key> 
    <one-to-many class="Event" column="VolatileEventContentId"></one-to-many> 
</bag> 

(列屬性是有效的在一個一對多的標籤?)

現在你需要定義一樣,該名稱的屬性,事:

<properties name="partialId" insert="false" update="false"> 
    <property name="LocationId" type="Int32" update="false" insert="false"/> 
    <property name="ContentProviderId" type="Int32" update="false" insert="false"/> 
</properties> 

您已經定義了LocationId和ContentProviderId。只需在屬性元素內移動這兩個屬性即可。

+0

不幸的是,property-ref不是一個可識別的屬性:( – 2010-03-20 16:28:55

0

首先,您在「LocationSearchView」 的映射中有一個錯誤,您將CategoryId列定義爲Property和Composite-id的一部分。這是錯誤的,但不幸的是它在構建映射時沒有被捕獲,並且通常在查詢對象時暴露出來。檢查IndexOutOfRangeException Deep in the bowels of NHibernate

它可能會混淆映射解析器。而我說兩個你映射你依靠的反思和公約,其意味着更嚴格的編程方法混淆因爲:

  1. 你不明確定義many-to-onebag元素class屬性,而是你希望NHibernate能夠從類定義本身中檢測類的類型。萬一你在課堂上LocationSearchView已進行如下設置IList<LocationSearchView> Events {get;set;} NHibernate的期望找到LocationSearchView類定義bag,因此需要3列映射集合
  2. 您有列名相同的屬性名,其使開發變得更容易(它實際上只是使映射的創建更容易,無論如何您只能創建一次或兩次),但是如果出現錯誤或更改,就很難檢測到哪裏出了問題。

因此,使您的映射更豐富,並刪除我提到的錯誤與CategoryId,也包括您的文章中的類!

相關問題