您不需要實體類型。看看任何類型的映射(它將類型名稱存儲在關係表中的數據庫中,但實體模型中不需要它)。
參見this blog post by ayende。
編輯:試圖寫的例子。
你可以爲每個標記的對象,一個自己的表,這是簡單,直接的,你甚至不需要任何類型:
<class name="Tag">
<!-- ... -->
<property name="Name"/>
</class>
<class name="Image">
<!-- ... -->
<bag name="Tags" table="Image_Tags">
<key column="Image_FK"/>
<many-to-many class="Tag" column="TagId "/>
</bag>
</class>
嘗試使用一些先進的功能,它映射到一個單一的表,但我認爲它不會以這種方式工作:
<class name="Tag">
<!-- ... -->
<property name="Name"/>
<bag name="Objects" table="tblTagEntity" access="noop">
<key column="TagId"/>
<many-to-any id-type="System.Int64" meta-type="System.String">
<meta-value
value="IMAGE"
class="Image"/>
<meta-value
value="BLOG"
class="Blog"/>
<column name="EntityType"/>
<column name="EntityId"/>
</many-to-any>
</bag>
</class>
<class name="Image">
<!-- ... -->
<bag name="Tags" table="tblTagEntity" where="EntityType='IMAGE'">
<key column="EntityId"/>
<many-to-many class="Tag" column="TagId "/>
</bag>
</class>
的位置招數:
access="noop"
指定實體模型中沒有屬性的外鍵,see this post。
where="EntityType='IMAGE'"
過濾加載的數據。
問題是最有可能的EntityType沒有設置爲任何有用的值。這可以在某個地方解決,但我認爲這不值得。
其他人可能有更好的主意。
編輯2:另一個(工作)溶液
使關聯表的實體:
在短
:
- 標籤=> TagEntity:未映射或一個(noop)
- TagEntity =>標籤:多對一
- TagEntity =>對象:任何
- 對象=> TagEntity:一個一對多的逆
這應該直截了當。
類:
class Tag
{
string Name { get; set; }
}
class TagEntity
{
Tag Tag { get; set; }
object Entity { get; set; }
}
class Image
{
IList<TagEntity> tags { get; private set; }
}
唯一的缺點似乎是,你必須確保雙向關聯是不裝載大量的數據是一致的。請注意,反向收集不會被存儲。
編輯2:性能說明
當您添加/移除標籤,你可以做一個伎倆。 TagEntity具有對標記實體的引用。該實體也有一個TagEntities的列表,但是這被標記爲反向。 (這意味着它們已被加載,但未被存儲。)
您可以在不加載實體的情況下添加和刪除標籤,而無需加載所有標籤。
添加:
- 獲取標記添加(或負載代理,如果你有標籤的ID)
- 負荷實體(只是代理,使用session.Load,在這裏沒有DB訪問)
- 創造新TagEntity,分配標籤和實體代理
- 保存TagEntity
刪除:
在會話中,您沒有將此標籤分配給TagEntity或從TagEntity中移除。這很好地工作,假設您只在此事務中添加或刪除標記。
我在標籤上定義了一個TagEntities列表,你可以做同樣的事情,不用加載所有的TagEntities來添加或刪除它。
見我的回答,我增加了一些更多的代碼。 – 2010-03-30 14:52:35
添加了一些性能註釋以添加/刪除標籤。順便說一下,在這裏附近的好獨角獸:-) – 2010-04-01 07:01:03