none
请问Entity Framework Code first 多对多的情况下如何进行级联删除? RRS feed

  • 问题

  • 情况是这样,有三个对象,

    Module > Page >Help

    这三个对象按照方向是一对多的关系。

    最后的Help又和自己是多对多的关系对象的代码大概是这样

     

     

      /// <summary>
      /// 模块
      /// </summary>
      public class Module :EntityWithGuid
      {
        #region 公开成员
        private string _Key = "";
        public string Key
        {
          get
          {
            return this._Key;
          }
          set
          {
            this._Key = value ?? string.Empty;
          }
        }
        private string _Name = "";
        public string Name
        {
          get
          {
            return this._Name;
          }
          set
          {
            this._Name = value ?? string.Empty; ;
          }
        }
    
        /// <summary>
        /// 所属页面列表
        /// </summary>
        public virtual ICollection<Page> Pages { get; set; }
    
        #endregion
      }
    
    
      /// <summary>
      /// 页面
      /// </summary>
      public class Page : EntityWithGuid
      {
        private string _Url;
        public string Url
        {
          get
          {
            return this._Url;
          }
          set
          {
            this._Url = value;
          }
        }
    
        private string _Name;
        public string Name
        {
          get
          {
            return this._Name.IsEmpty() ? this.Url : this._Name;
          }
          set
          {
            this._Name = value ?? string.Empty; ;
          }
        }
    
        public virtual ICollection<Help> Helps { get; set; }
    
        public virtual Module Module { get; set; }
      }
    
    
      public class Help : EntityWithGuid
      {
    
        private string _Key;
        public string Key
        {
          get
          {
            return this._Key;
          }
          set
          {
            this._Key = value;
          }
        }
    
        private string _Title;
        public string Title
        {
          get
          {
            return this._Title;
          }
          set
          {
            this._Title = value;
          }
        }
    
        public ICollection<Help> Helps { get; protected set; }
    
        public virtual Page Page { get; set; }
      }
    
          modelBuilder.Entity<Page>()
            .HasRequired<Module>(t => t.Module)
            .WithMany(t => t.Pages)
            .WillCascadeOnDelete(true);
    
          modelBuilder.Entity<Help>()
            .HasMany<Help>(t => t.Helps)
            .WithMany()
            .Map(m =>
            {
              m.ToTable("RelatedHelp");
            });
    
          modelBuilder.Entity<Help>()
            .HasRequired<Page>(t => t.Page)
            .WithMany(t => t.Helps).WillCascadeOnDelete(true);
    

    映射关系如上,一对多的情况可以级联删除(WillCascadeOnDelete)但是多对多的时候点不出来WillCascadeOnDelete。

    一但存在关联帮助就会删除失败。

    请问要如何做呢?谢谢。

     

    2011年6月9日 5:50

答案

  • 从英文版论坛看到一个解决办法

    设置两个一对多的关系:http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/814e7fbc-ff04-41fc-8ae0-92bc0238638d/

    SSDL:

    =================================================================================

          <Association Name="FK_TagArticle_Article">

              <End Role="Article" Type="TestDBModel.Store.Article" Multiplicity="1">

                <OnDelete Action ="Cascade" />

             </End>

              <End Role="TagArticle" Type="TestDBModel.Store.TagArticle" Multiplicity="*" />

              <ReferentialConstraint>

                <Principal Role="Article">

                  <PropertyRef Name="ArticleID" />

                </Principal>

                <Dependent Role="TagArticle">

                  <PropertyRef Name="ArticleID" />

                </Dependent>

              </ReferentialConstraint>

            </Association>

            <Association Name="FK_TagArticle_Tag">

              <End Role="Tag" Type="TestDBModel.Store.Tag" Multiplicity="1">

                <OnDelete Action="Cascade" />

             </End>

              <End Role="TagArticle" Type="TestDBModel.Store.TagArticle" Multiplicity="*" />

              <ReferentialConstraint>

                <Principal Role="Tag">

                  <PropertyRef Name="TagID" />

                </Principal>

                <Dependent Role="TagArticle">

                  <PropertyRef Name="TagID" />

                </Dependent>

              </ReferentialConstraint>

            </Association>

    2011年6月13日 7:52

全部回复

  • 是否无法在多对多上应用级联删除呢?

    我现在数据库中建了几个表,配置了相应的外键,然后用Power Tools,生成了映射,运行后发现之前设置的级联删除到了多对多这里就消失了。

    一对多则没问题。

    2011年6月9日 7:09
  • 你好,我觉得在表的关系为一对一或者一对多的表之间应用级连删除是合理的,但是如果在多对多的表之间应用级连删除,会不会造成一种循环删除的后果呢,如果是这样的话,可能就会造成死锁,或者是全部数据都被删除了,因此是不合理的。

    所以我认为正是考虑到这层因素,才没有在多对多关系的表中应用级连删除。这应该是一个By Design的问题。

    希望能帮到你,

     

    谢谢。


    Jackie Sun [MSFT]
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载  MSDN 论坛好帮手



    2011年6月13日 6:18
    版主
  • 你好,我认同你有关死锁的方法说法。

    但问题是如果多对多的关系出现在任意一环中那么其所有父对象就都不能级联删除了。

    比如我我说的结构上的Module和Page两个对象,删除它们任何一级,都会引起删除Help的操作,实在有点郁闷。

    如果能有个OnDelete之类的设置就好了,就可以在删除Help的时候单独处理他的逻辑了

    public IDbSet<Help> Helps { get; set; }

    Helps.OnDelete = 

    类似这样。

    当然一般删除一个对象会在关联表中删除与其有关的所有关联信息,而不能删除对象本身,如果Entity Framework能直接处理这种情况就最理想了。

     

    2011年6月13日 7:19
  • 从英文版论坛看到一个解决办法

    设置两个一对多的关系:http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/814e7fbc-ff04-41fc-8ae0-92bc0238638d/

    SSDL:

    =================================================================================

          <Association Name="FK_TagArticle_Article">

              <End Role="Article" Type="TestDBModel.Store.Article" Multiplicity="1">

                <OnDelete Action ="Cascade" />

             </End>

              <End Role="TagArticle" Type="TestDBModel.Store.TagArticle" Multiplicity="*" />

              <ReferentialConstraint>

                <Principal Role="Article">

                  <PropertyRef Name="ArticleID" />

                </Principal>

                <Dependent Role="TagArticle">

                  <PropertyRef Name="ArticleID" />

                </Dependent>

              </ReferentialConstraint>

            </Association>

            <Association Name="FK_TagArticle_Tag">

              <End Role="Tag" Type="TestDBModel.Store.Tag" Multiplicity="1">

                <OnDelete Action="Cascade" />

             </End>

              <End Role="TagArticle" Type="TestDBModel.Store.TagArticle" Multiplicity="*" />

              <ReferentialConstraint>

                <Principal Role="Tag">

                  <PropertyRef Name="TagID" />

                </Principal>

                <Dependent Role="TagArticle">

                  <PropertyRef Name="TagID" />

                </Dependent>

              </ReferentialConstraint>

            </Association>

    2011年6月13日 7:52
  • Great, man!

     对了,你的那个有关EFPowerTool的问题,我回复了,请查看一下。

    http://social.msdn.microsoft.com/Forums/zh-CN/adonetzhchs/thread/9b18d662-28fc-45f3-9206-ef4ea226c2e3/#b0423537-9686-4ec0-98e5-90314e152da4

    另外,这个问题正在与EF Design Team沟通,来确定这个是不是个Bug,暂时的解决方案就是我回复中提到的。

    希望能帮到你,


    Jackie Sun [MSFT]
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载  MSDN 论坛好帮手




    2011年6月13日 8:53
    版主