如何以允许成功首次迁移代码的方式正确构建以下模型?

时间:2015-11-04 16:52:57

标签: c# entity-framework ado.net ef-code-first cascading-deletes

感谢您的光临。

我想创建以下Image域模型:

    [Table("Image")]    
    public class Image
    {
        [Key]
        public int Id { get; set; }
        [Required(ErrorMessage = "Please enter a title.")]
        public string Title { get; set; }
        [Required(ErrorMessage = "Please enter a caption.")]
        public string Caption { get; set; }
        [Required(ErrorMessage = "Please enter a file.")]
        public string File { get; set; }
    }

然后,我想要多个其他模型来使用它。例如:

[Table("Product")]
public class Product
{
    [Key]
    public int Id { get; set; }
    [Required(ErrorMessage = "Please enter a title.")]
    public string Title { get; set; }
    [Required(ErrorMessage = "Please enter a description.")]
    public string Description { get; set; }
    public int ImageId { get; set; }
    public virtual Image Image { get; set; }       
}

[Table("User")]
public class User
{
    [Key]
    public int Id { get; set; }
    [Required(ErrorMessage = "Please enter a name.")]
    public string Name { get; set; }
    public int ImageId { get; set; }
    public virtual Image Image { get; set; }        
}

管理(创建)ProductUser执行时需要单个图片。此外,用于ProductUser的图片不会被任何其他实体使用。

问题

当我尝试通过程序包管理器控制台(PM> update-database)将此代码第一个模型部署到数据库时,出现以下错误:

Introducing FOREIGN KEY constraint 'FK_dbo.Product_dbo.Image_ImageId' on table 'Product' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

因此,返回的消息表明我改变了SQL语句,因为我通过软件包管理器控制台/ CodeFirst自动执行此操作。

问题

也就是说,如何创建一个公共Image实体模型,将其用作多个其他实体的必需属性,并仍然通过CodeFirst部署而不违反multiple cascade paths规则?

提前致谢。

1 个答案:

答案 0 :(得分:2)

我一步一步地复制了你的场景,但我没有收到任何错误。但是,我相信您已经有一个现有的数据库,这可能会导致您上面描述的错误。

要解决cycles or multiple cascade paths error,只需使用Fluent API映射关系,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Product>()
        .HasRequired(i => i.Image)
        .WithMany()
        .HasForeignKey(i => i.ImageId)
        .WillCascadeOnDelete(false);

    modelBuilder.Entity<User>()
        .HasRequired(i => i.Image)
        .WithMany()
        .HasForeignKey(i => i.ImageId)
        .WillCascadeOnDelete(false);

    base.OnModelCreating(modelBuilder);
}

我认为应该足以解决您的问题。

你的第二个问题更复杂:

  

管理(创建)我想要的单个产品或用户时   图像是必需的。此外,用于产品或用户的图像将   不被任何其他实体使用。

使用您当前的数据库结构,我无法在数据库级别查看它是如何实现的。我能想到的最简单的解决方法是:

  1. ImageUsers创建一个独立的Projects实体(如UserImage,ProductImage)(我认为这不值得)
  2. 在应用程序级别验证关系
  3. 希望它有所帮助!