【问题标题】:Delete from <Map>从 <地图> 中删除
【发布时间】:2009-08-07 12:40:03
【问题描述】:

我有地图:

<class name="User" table="Users" lazy="false">
  <id name="id" type="Int32" column="id">
    <generator class="identity" />
  </id>
  <property name="name" column="name" type="String"/>
  <map name="Urls" table="UserUrl" lazy="true" inverse="true" cascade="all">
     <key column="user_id"></key>
     <index column="url_type_id" type="Int32"/>
     <one-to-many class="UserUrl"/>
   </map>
</class>

<class name="UserUrl" table="UserUrl" lazy="false">
  <id name="id" type="Int32" column="id">
    <generator class="identity"/>
  </id>
  <property name="user_id" column="user_id" type="Int32" not-null="true"/>
  <property name="UrlType" column="url_type_id" type="Int32" not-null="true"/>
  <property name="Url" column="url" type="String" not-null="true"/>
</class>

我也明白了

class User
{
  IDictionary<int,UserUrl> Urls;
 ....
}

User currentUser = FindById(2);
currentUser.Urls.Remove(5);

所以我从 Url 的关联集合中删除了一项。然后我调用SaveOrUpdateCopy(...),但是表UserUrl中的url没有删除,也没有错误。

有人知道如何从集合和数据库中删除子项吗?

【问题讨论】:

    标签: nhibernate map


    【解决方案1】:

    元素的 inverse 设置为 false。

    【讨论】:

    • 我试了一下,但我得到错误“无法将值 NULL 插入列 'user_id',表 'dbo.UserUrl';列不允许空值。更新失败。语句已终止。 "
    【解决方案2】:

    我尝试在 google 中搜索,但没有关于 &lt;map&gt;&lt;one-to-many &gt;&lt;map&gt;&lt;composite-element&gt; 之间区别的信息,所以我使用 &lt;map&gt;&lt;one-to-many &gt;
    <map name="Urls" table="UserUrl" lazy="true" cascade="all-delete-orphans"> <key column="user_id"/> <index column="url_type_id" type="Int32"/> <composite-element> <property name="UrlType" column="url_type_id" type="Int32" not-null="true"/> <property name="Url" column="url" type="String" not-null="true"/> </composite-element> </map>


    如果 Url 不是独立实体,具有自己的 Id,那么您可以将其映射为
    复合元素。 url 被视为值类型。
    不再有类 UserUrl 映射。 我在其他代码中使用 UserUrl 类

    【讨论】:

    • 你不懂组件。看到我的答案,我添加了一个链接。顺便说一句,如果您实际上是在评论答案,请不要回答您的问题。你可能会被否决。
    • 忘了告诉你这个秘密:你可以选择几行一起显示为源代码(这只是在每行之前添加4个空格)。它还在每一行中断,并有一些漂亮的语法突出显示。不要同时使用

      。只需选择文本并使用编辑器顶部的按钮。
    【解决方案3】:

    试试这个:

    <map name="Urls" lazy="true" cascade="all-delete-orphans">
    
    • 你不需要table,因为表是在类UserUrl映射中定义的
    • 如果不是,则不应将其反转
    • 您应该级联它 all-delete-orphan 以告诉 NH 删除从集合中删除的项目。

    与您的问题无关,为什么您的网址中有这个?

    <property name="user_id" column="user_id" type="Int32" not-null="true"/>
    

    您正在那里映射外键!我永远都不敢这样做。


    实际上,我不确定您是否应该像这样实际映射它:

    <map name="Urls" table="UserUrl" lazy="true" cascade="all-delete-orphans">
       <key column="user_id"/>
       <index column="url_type_id" type="Int32"/>
       <composite-element>
         <property name="UrlType" column="url_type_id" type="Int32" not-null="true"/>
         <property name="Url" column="url" type="String" not-null="true"/>
       </composite-element>
     </map>
    

    如果 Url 不是独立实体,有自己的 Id,那么您可以将其映射为复合元素。 url 被视为值类型。没有类UserUrl 映射了。

    编辑:

    • 参见NH Reference Chapter 7,它解释了组件。
    • 如果您在引用中遇到非空问题,只需删除非空 外键约束。 NH 需要插入一些列来获取 如果您使用generator class="identity",则主键,所以它存储 一个临时的空值。

    【讨论】:

    • 非常感谢您的回答。我使用 : 插入新的 UserUrl。我尝试从映射和类中删除它并得到错误“无法将值 NULL 插入列 'user_id' 表 'dbo.UserUrl'”所以它是必要的
    【解决方案4】:

    -顺便说一句,如果您实际上是在评论某个问题,请不要回答您的问题 回答。你可能会被否决

    -问题是我没有stackoverflow帐户,所以以相同名称登录网站的唯一方法是在我的帖子下输入姓名和电子邮件。我尝试在该站点上使用相同的名称和电子邮件注册帐户,但是当我登录时,它会将我视为新用户(而不是我第一次登录时)。
    所以我别无选择。

    我还发现工作代码是

    <map name="Urls" lazy="true" cascade="all-delete-orphans" inverse="true">
    

    没有 inverse="true" 它不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-24
      相关资源
      最近更新 更多