首页 > 解决方案 > EF 框架代码优先 - 未生成正确的数据库脚本

问题描述

我已经创建了上下文类,并且在 EF 中。下面是从 EF 创建脚本时遇到问题的两个实体。 在此处输入图像描述

解释一下Account和Post的关系,基本上1个Account可以有0个或多个Post。

以下是我特别关注的 3 个场景,因为 EF 没有正确生成脚本(据我了解)。

  1. 1个账号可以创建多个帖子。
  2. 1个账号可以修改多个帖子。
  3. 1个账号可以发布很多帖子。

下面是我的两个类的代码;

[Table("Account")]
public class Account : IModificationHistory
{
    [Key]
    public int ID { get; set; }

    [Required]
    [Column("firstName")] //db column name
    [MaxLength(255, ErrorMessage = "First name should be 255 characters or less")]
    [Display(Name = "First Name")] //displayed in UI
    public string FirstName { get; set; }

    [Required]
    [Column("lastName")] //db column name
    [MaxLength(255, ErrorMessage = "Last name should be 255 characters or less")]
    [Display(Name = "Last Name")] //displayed in UI
    public string LastName { get; set; }

    [Required] 
    [Column("emailAddress")] //db column name
    [MaxLength(255, ErrorMessage = "Email address should be 255 characters or less")]
    [DataType(DataType.EmailAddress)] //for UI presentation only
    [Display(Name = "Email Address")] //displayed in UI
    [EmailAddress(ErrorMessage = "Invalid email address format")]
    public string EmailAddress { get; set; }

    [Required]
    [Column("password")]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    [Column("status")]
    public int Status { get; set; }

    [Column("role")]
    public int Role { get; set; }

    [Column("salt")]
    public string Salt { get; set; }

    [Column("dateCreated")]
    public DateTime DateCreated { get; set; }

    [Column("dateModified")]
    public DateTime DateModified { get; set; }


    public List<Post> ListPost { get; set; }

}

[Table("Post")]
public class Post : IModificationHistory
{
    [Key]
    public int ID { get; set; }

    [Required(ErrorMessage = "Title is mandatory")]
    [Column("title")]
    [MaxLength(255, ErrorMessage = "Title should be 255 characters or less")]
    public string Title { get; set; }

    [Required(ErrorMessage = "Content is mandatory")]
    [Column("content")]
    public string Content { get; set; }

    [Column("incidentID")]
    [Display(Name = "Related Incident")]
    public string IncidentID { get; set; }

    [Column("tagID")]
    [Display(Name = "Tag")]
    public string TagID { get; set; }

    [Column("dateModified")]
    public DateTime DateModified { get; set; }

    [Column("dateCreated")]
    public DateTime DateCreated { get; set; }

    [Column("datePublished")]
    public DateTime DatePublished { get; set; }

    [Column("status")]
    public int Status { get; set; }

    [Column("contactGroupID")]
    public int ContactGroupID { get; set; }

    //foreign key reference to Account table
    [Column("createdByAccountID")]
    public int CreatedByAcccountID { get; set; }

    //foreign key reference to Account table
    [Column("modifiedByAccountID")]
    public int ModifiedByAccountID { get; set; }        

    //foreign key reference to Account table
    [Column("publishedByAccountID")]
    public int PublishedByAccountID { get; set; }


    public Account ModifiedByAccount { get; set; }

    public Account CreatedByAccount { get; set; }

    public Account PublishedByAccount { get; set; }

}

当我运行 add-migration 命令时,以下是它生成的脚本

CreateTable(
            "dbo.Account",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    firstName = c.String(nullable: false, maxLength: 255),
                    lastName = c.String(nullable: false, maxLength: 255),
                    emailAddress = c.String(nullable: false, maxLength: 255),
                    password = c.String(nullable: false),
                    status = c.Int(nullable: false),
                    role = c.Int(nullable: false),
                    salt = c.String(),
                    dateCreated = c.DateTime(nullable: false),
                    dateModified = c.DateTime(nullable: false),
                })
            .PrimaryKey(t => t.ID);
        
        CreateTable(
            "dbo.Post",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    title = c.String(nullable: false, maxLength: 255),
                    content = c.String(nullable: false),
                    incidentID = c.String(),
                    tagID = c.String(),
                    dateModified = c.DateTime(nullable: false),
                    dateCreated = c.DateTime(nullable: false),
                    datePublished = c.DateTime(nullable: false),                      
                    status = c.Int(nullable: false),
                    contactGroupID = c.Int(nullable: false),
                    modifiedByAccountID = c.Int(nullable: false),
                    createdByAccountID = c.Int(nullable: false),
                    publishedByAccountID = c.Int(nullable: false),
                    CreatedByAccount_ID = c.Int(),
                    Account_ID = c.Int(),
                })
            .PrimaryKey(t => t.ID)
            .ForeignKey("dbo.Account", t => t.CreatedByAccount_ID)
            .ForeignKey("dbo.Account", t => t.modifiedByAccountID, cascadeDelete: true)
            .ForeignKey("dbo.Account", t => t.publishedByAccountID, cascadeDelete: true)
            .ForeignKey("dbo.Account", t => t.Account_ID)
            .Index(t => t.modifiedByAccountID)
            .Index(t => t.publishedByAccountID)
            .Index(t => t.CreatedByAccount_ID)
            .Index(t => t.Account_ID);

在脚本中我的问题是,它创建了两列“createdByAccountID = c.Int(nullable: false)”列和“CreatedByAccount_ID = c.Int()”列,我认为它们具有相同的目的并创建了另一个额外的列“Account_ID = c.Int()”。谁能指出我在这里做错了什么?

谢谢。

标签: entity-frameworkentity-framework-6

解决方案


我从 EF 发现了上述行为的问题。这是因为我没有配置 InverseProperty。

在 Post 类中,我进行了以下更改;

  • 我已删除以下属性

     [Column("createdByAccountID")]
     public int CreatedByAccountID { get; set; }
    
     [Column("modifiedByAccountID")]
     public int ModifiedByAccountID { get; set; }
    
     [Column("publishedByAccountID")]
     public int PublishedByAccountID { get; set; }
    
  • 并修改了以下属性

     [Column("createdByAccountID")]
     public Account CreatedByAccount { get; set; }
    
     [Column("modifiedByAccountID")]
     public Account ModifiedByAccount { get; set; }
    
     [Column("publishedByAccountID")]
     public Account PublishedByAccount { get; set; }
    

在 Account 类中,我进行了以下更改;

  • 删除了以下属性

     public List<Post> ListPost { get; set; }
    
  • 并添加了以下属性

     [InverseProperty("CreatedByAccount")]
     public List<Post> ListPostCreated { get; set; }
    
     [InverseProperty("ModifiedByAccount")]
     public List<Post> ListPostModified { get; set; }
    
     [InverseProperty("PublishedByAccount")]
     public List<Post> ListPostPublished { get; set; }
    

进行上述更改后,当我执行 add-migration 时,生成了正确的 db 脚本。下面是生成的脚本;

CreateTable(
        "dbo.Post",
        c => new
            {
                ID = c.Int(nullable: false, identity: true),
                title = c.String(nullable: false, maxLength: 255),
                content = c.String(nullable: false),
                incidentID = c.String(),
                tagID = c.String(),
                dateModified = c.DateTime(nullable: false),
                dateCreated = c.DateTime(nullable: false),
                datePublished = c.DateTime(nullable: false),                      
                status = c.Int(nullable: false),
                contactGroupID = c.Int(nullable: false),
                CreatedByAccount_ID = c.Int(),
                ModifiedByAccount_ID = c.Int(),
                PublishedByAccount_ID = c.Int(),
            })
        .PrimaryKey(t => t.ID)
        .ForeignKey("dbo.Account", t => t.CreatedByAccount_ID)
        .ForeignKey("dbo.Account", t => t.ModifiedByAccount_ID)
        .ForeignKey("dbo.Account", t => t.PublishedByAccount_ID)
        .Index(t => t.CreatedByAccount_ID)
        .Index(t => t.ModifiedByAccount_ID)
        .Index(t => t.PublishedByAccount_ID);

希望这对遇到同样问题的人有所帮助。


推荐阅读