首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NHibernate映射具有唯一键约束的组件列表

NHibernate映射具有唯一键约束的组件列表
EN

Stack Overflow用户
提问于 2011-03-11 23:10:44
回答 1查看 2.3K关注 0票数 2

我正在尝试映射一个组件列表,该列表包含对其值的唯一键约束。

下面是这些类的“修剪”示例:

代码语言:javascript
复制
public class MyObject
{
    public virtual int Id { get; set; }
    public virtual IList<Alias> Aliases { get; set; }
}

public class Alias
{
    public Alias(string type, string value)
    {
        Type = type;
        Value = value;
    }

    public virtual string Type { get; protected set; }
    public virtual string Value { get; protected set; }
}

以及来自MyObject的相关NHibernate映射(为简洁起见,已对类型进行了修剪):

代码语言:javascript
复制
  <list cascade="all-delete-orphan" name="Aliases" table="MyObject_Aliases" mutable="true">
      <key>
        <column name="MyObject_id" />
      </key>
      <index>
        <column name="`Index`" />
      </index>
      <composite-element class="Alias">
        <property name="Type" type="System.String">
          <column name="Type" unique-key="UK_Alias" />
        </property>
        <property name="Value" type="System.String">
          <column name="Value" unique-key="UK_Alias" />
        </property>
      </composite-element>
    </list>

这样做的目的是防止两个MyObjects包含相同的别名。

将新别名添加到MyObject时,此操作效果非常好。但是,如果要从列表中删除别名,其中在删除的别名之后有别名,则NHibernate会尝试重新排序列表,这会导致键冲突。

NHibernate生成的SQL示例如下:

代码语言:javascript
复制
-- statement #1, saving MyObject.Aliases
INSERT INTO MyObject_Aliases
           (MyObject_id,
            "Index",
            Type,
            Value)
VALUES     (101 /* @p0 */,
            0 /* @p1 */,
            'A' /* @p2 */,
            'ALIAS1' /* @p3 */)

INSERT INTO MyObject_Aliases
           (MyObject_id,
            "Index",
            Type,
            Value)
VALUES     (101 /* @p0 */,
            1 /* @p1 */,
            'A' /* @p2 */,
            'ALIAS2' /* @p3 */)

-- statement #2, updating MyObject.Aliases after removing the first list item
UPDATE MyObject_Aliases
SET    Type = 'A' /* @p0 */,
       Value = 'ALIAS2' /* @p1 */
WHERE  MyObject_id = 101 /* @p2 */
       AND "Index" = 0 /* @p3 */

本例中的语句#2抛出:

代码语言:javascript
复制
NHibernate.Exceptions.GenericADOException : could not update collection rows: [MyObject.Aliases#101][SQL: UPDATE MyObject_Aliases SET Type = ?, Value = ? WHERE MyObject_id = ? AND "Index" = ?]
  ----> System.Data.SQLite.SQLiteException : Abort due to constraint violation
columns Type, Value are not unique

根据实际发生的情况,异常本身是非常有意义的,但是我如何让它真正按照预期工作呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-03-12 01:22:39

如果您的集合不需要索引,那么您可能应该使用集合映射。set是一种集合类型,它保证没有重复项。列表是一种可以被索引的集合类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5274609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档