【问题标题】:EF Doesn't Delete Records For Fluent API - Many To Many RelationshipEF 不会删除 Fluent API 的记录 - 多对多关系
【发布时间】:2013-04-05 02:48:55
【问题描述】:

我有 2 个实体,

  • 新闻
  • 文件附件

我想使用 code-first fluent API 进行配置,以便每个新闻可以有 0,1 或多个附件。

这是我现在正在使用的

   public NewsMap()
    {
        this.ToTable("News"); // Table Name
        this.HasKey(m => m.Id); // Primary Key

        // Field Definition            
        this.Property(m => m.Title).HasMaxLength(255).IsRequired();
        this.Property(m => m.Body).HasColumnType("Text").IsRequired();
        this.Property(m => m.Summary).HasMaxLength(1000).IsRequired();
        this.Property(m => m.AuthorId).IsRequired();

        this.Property(m => m.CreatedOn).IsRequired();
        this.Property(m => m.UpdatedOn).IsRequired();

        this.HasMany(m => m.Attachments).WithMany().Map(m => m.MapLeftKey("NewsId").MapRightKey("AttachmentId"));
    }

public class FileAttachmentMap : EntityTypeConfiguration<FileAttachment>
{
    public FileAttachmentMap()
    {
        this.ToTable("FileAttachments"); // Table Name
        this.HasKey(m => m.Id); // Primary Key

        // Field Definition            
        this.Property(m => m.DisplayName).HasMaxLength(256).IsRequired();
        this.Property(m => m.PhysicalFileName).HasMaxLength(256).IsRequired();
        this.Property(m => m.Extension).HasMaxLength(50).IsRequired();
        this.Property(m => m.IsImage).IsRequired();
        this.Property(m => m.ThumbTiny).HasMaxLength(275).IsOptional();
        this.Property(m => m.ThumbSmall).HasMaxLength(275).IsOptional();
        this.Property(m => m.ThumbMid).HasMaxLength(275).IsOptional();
        this.Property(m => m.ByteSize).IsRequired();
        this.Property(m => m.StorageType).IsRequired();   

        this.Property(m => m.CreatedOn).IsRequired();
        this.Property(m => m.UpdatedOn).IsRequired();
    }
}

此映射正确生成了一个名为 NewsFileAttachment 的中间表,其中包含两个字段:

  • NewsId
  • 附件 ID

当我调用 News.Attachments.Add(Attachment); 时在新闻实体上它会在 Attachment 和 NewsAttachment 表中正确添加记录。

当我从 News.Attachments 中删除某些列表项时,它会正确地从 NewsAttachment 表中删除记录,但不会删除 FileAttachment 表中的记录。我也想删除它。

有人可以建议一个更好的 Fluent API 配置来实现这一点吗?

谢谢, 阿米特

编辑

就我而言,FileAttachment 存储用于各种目的的文件。我的博客实体也有附件。因此,有两个中间表 BlogAttachments 和 FileAttachments。现在,如果我使用 WithOptional 作为(我不能使用 WithRequired,因为我在 FileAttachment 表中都需要 BlogId 和 NewsId),我可以摆脱中间表,但仍然删除不会从 FileAttachment 表中删除记录,它只是让 NewsId/博客 ID 为空。

有什么建议吗?主要的是我不想用我在 FileAttachment 表中的所有字段创建单独的表。

【问题讨论】:

    标签: entity-framework ef-code-first code-first fluent-interface entity-framework-migrations


    【解决方案1】:

    这是意料之中的 - 因为它创建了多对多和额外的表 - 级联仅适用于该表。

    在您的 NewsAttachment,因为它通过一个连接表。因此你不能指望例如附件被删除,如果新闻有 - 因为附件可能有其他与之相关的新闻。

    另请参阅这个 - 它有点相关。
    One to Many Relationship with Join Table using EF Code First

    即如果您的结构允许不明确创建多对多(不要在两侧放置集合,或在流利的配置中类似)。

    在您的情况下提供您的“附件”在 News 之间不可重复使用 - 然后只需在 News 中放置一个集合导航属性 - 并留下不带任何附件的附件 - 或制作一个“FK”,来自附件的单实例导航(如“父”),如果你需要它。

    另一方面,如果 attach... 可以由不同的父 news 记录 - 那么你不应该有级联删除。

    注意:检查您生成的迁移脚本 - 或 SQL/Db - 以查看它创建的确切内容 - 并确保没有创建中间表 - 并且只有一个来自“附件”的“FK” '到'新闻'。

    编辑:

    modelBuilder.Entity<News>()
        .HasMany(c => c.Attachments)
        .WithOptional() // or WithRequired (test to see which is better for you)
        .WillCascadeOnDelete(true);
    

    ...在新闻中创建一个public ICollection&lt;FileAttachment&gt; Attachments {get;set;}
    (实际上集合属性就是你所需要的——但配置是为了确保你得到你想要的东西)

    这将使您成为一对多(或多对一),这是您的数据的性质(正如您在 cmets 中所说的那样) - 您可以进行级联删除。

    【讨论】:

    • 您好,感谢您的回复。我的问题是当我从新闻中删除与附件的关系时,是否仍然可以保留中间表并删除附件?我知道从技术上讲这可能是不正确的,但根据我的架构,我知道单个附件记录将通过中间表与一个且仅一个其他实体相关联。如果这不可能,您能否建议任何其他没有中间表的配置,从附件表中删除记录?
    • 嗨,阿米特 - 不可能 - 据我所知和所见。请参阅我的编辑以了解该做什么 - 这是唯一的方法 - 我认为它“适合”你想要的。
    • 感谢@NSGaga,在我的例子中,FileAttachment 存储用于各种目的的文件。我的博客实体也有附件。两个中间表 BlogAttachments 和 FileAttachments。现在,如果我按照您的建议使用 WithOptional(我不能使用 WithRequired),因为我在 FileAttachment 表中都需要 BlogId 和 NewsId),我可以摆脱中间表,但仍然删除不会从 FileAttachment 表中删除记录,它只是使 NewsId/BlogId 为 NULL。有什么建议吗?主要的是我不想用我在 FileAttachment 表中的所有字段创建单独的表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多