1

我有2个实体,

  • 消息
  • 文件附件

我想使用代码优先的 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 的中间表,其中包含两个字段:

  • 新闻ID
  • 附件 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 表中的所有字段创建单独的表。

4

1 回答 1

0

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

News您的and 之间没有直接的“FK”关系Attachment,因为它通过连接表。因此,如果新闻确实删除了例如附件,则您不能期望删除 - 因为附件可能有其他与之相关的新闻。

另请参阅这个 - 它有点相关。
使用 EF 代码优先与连接表建立一对多关系

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

在您的情况下,提供您的“附件”在两者之间不可重用News- 然后只需将集合导航属性放入News- 并留下附件没有任何 - 或从附件制作“FK”,单实例导航(如“父” ) 如果你需要的话。

另一方面,如果 anattach...可以由不同的 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<FileAttachment> Attachments {get;set;}在新闻中制作一个。
(实际上集合属性就是你所需要的——但配置是为了安全你得到你想要的)

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

于 2013-04-12T14:41:33.527 回答