我试图引用一些子实体,其中部分父项复合键不是全部,为什么我不能?当我使用以下映射而不是注释时,会发生这种情况。
我收到以下错误
表中的外键 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 :(得分: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>
的{{1}}包的LocationSearchView
元素。 Events
指定子中的哪些列指向父。
让我们考虑当您(或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
“one”<key>
无法拥有“很多”LocationSearchView
s。相反,它应该是相反的方式。鉴于这些表格,实际上存在从Event
到Event
的一对多关系。
我不知道这个问题的正确解决方案是什么,因为我不知道你想要完成什么,但希望这有助于阐明究竟是什么问题。
答案 1 :(得分:0)
我从未使用过nhibernate,但我认为映射与hibernate非常相似。
如果您不希望您的一对多(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。只需在properties元素中移动这两个属性即可。
答案 2 :(得分:0)
首先,您在“LocationSearchView
”的映射中出错
您将CategoryId
列定义为Property和Composite-id的一部分。这是错误的,但不幸的是,在构建映射时没有捕获它,并且通常在查询对象时暴露。检查IndexOutOfRangeException Deep in the bowels of NHibernate
可能会混淆映射解析器。我说的是令人困惑,因为在你的映射中,你依赖于反射和约定,这意味着更严格的编程方法:
class
和many-to-one
元素的bag
属性,而是希望NHibernate从类定义本身检测类类型。如果您在类LocationSearchView
中设置了任何机会,则以下IList<LocationSearchView> Events {get;set;}
nhibernate会为定义的LocationSearchView
找到bag
类,因此需要3列来映射集合所以,让你的映射更丰富,并删除我在CategoryId
中提到的错误,也包括你帖子中的类!