【问题标题】:Preventing duplicate tag names with many-to-many NHibernate mapping使用多对多 NHibernate 映射防止重复的标签名称
【发布时间】:2010-10-21 00:22:34
【问题描述】:

我正在使用 NHibernate 将我的 Item 类持久化到 SQL 数据库。 Item 类具有 Item.Tags 类型的 ICollection<Tag> 属性,我使用以下 NHibernate 配置对其进行映射。

<set name="Tags" table="TagLinks" cascade="all" lazy ="false">
  <key column="ItemId" />
  <many-to-many class="Tag" column="TagID" />
</set>

这也是我的 Tag 类的映射,它只有一个 int ID 和一个字符串名称。

<class name="RCL.Tag" table="Tags" lazy="false" >
    <id name ="TagID" column="TagID" >
        <generator class="native"/>
    </id>
    <property name="Name" not-null="true"/>
</class>

这一切都很好,但它允许创建具有相同名称的重复标签。因此,下面的代码将在 Tags 表中创建三个单独的“foo”条目,它们都具有单独的 ID。

myItem1.Tags.Add(new Tag("Foo"));
myItem2.Tags.Add(new Tag("Foo"));
myItem3.Tags.Add(new Tag("Foo"));

这显然不是我想要的工作方式。我可以向 Tags.Name 列添加唯一约束,但上面的代码只会引发异常。

在对象模型方面,我希望能够通过编辑Tag 或String 的集合来简单地从Item 添加和删除标签。但是,当我的项目被持久化到数据库时,它应该确定需要创建哪些新标签以及何时应该映射到标签表中的现有条目。

我还考虑将其更改为基于值的一对多关系,其中Item.Tags 将只是一个IList&lt;String&gt;,并将映射到单个标签表,其中每个Item 上的每个单独标签都有条目.这也可以,但我想我更喜欢第一个,因为它可以更有效地查找具有特定标签的项目。我对关系数据库也很陌生。所以我什至不确定这是否应该是一个问题。

【问题讨论】:

  • 我很好奇为什么你真的希望这是一个数据库解决方案?
  • 我不确定我是否理解您的评论。数据库解决方案的替代方案是什么?

标签: c# .net nhibernate nhibernate-mapping


【解决方案1】:

拥有两个同名的 Tag 实体是没有用的,因为您必须按名称搜索,否则结果将不是您所期望的。

因此,唯一可能的解决方案是您考虑过的解决方案:使 Tag.Name 唯一,或完全删除实体并将标签映射为 ICollection。

由于空间很便宜,而且无论如何您都会对该列进行索引,因此后者是一种更简单的方法,尽管如果您想要类似 stackoverflow 的标签管理(同义词等),您会失去一点灵活性

【讨论】:

    【解决方案2】:

    如果你想试试DDD,那么解决方案应该是这样的:

    public class Item
    {
      public IList<Tag> Tags {get;set;}
      public void AddTag(String tagName)
      {
        var tagAlreadyExists = Tags.Any(a=>String.Compare(a.Name,tagName,StringComparison.OrdinalIgnoreCase)==0;
        if (tagAlreadyExists )
          return; // Or throw exception
        Tags.Add(new Tag(tagName));
      }
    }
    

    基本上,聚合根(项目)负责执行标签必须唯一的规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      相关资源
      最近更新 更多