代码优先迁移使用下划线添加添加字段

时间:2014-06-11 02:37:16

标签: c# migration code-first entity-framework-6

我有一个链接了两个表的数据库。当我运行初始迁移时,我会添加一个额外的Analysis_Id字段,即使这不在我的模型中。

我的基本设置是分析将随时间推移(1到多个)结帐的历史记录。但是在任何时候它都只有1(由Analysis表上的CheckedOutById表示)。

public class CheckOut
{
    public int Id { get; set; }

    [ForeignKey("ByUser")]
    public int ByUserId { get; set; }        
    public virtual UserProfile ByUser { get; set; }

    public int AnalysisId { get; set; }
    [ForeignKey("AnalysisId")]
    public virtual Analysis Analysis { get; set; }

    public DateTime At { get; set; }
}

public class Analysis
{
    public Analysis()
    {
        Revisions = new Collection<AnalysisRevision>();
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public int SupplierSeasonId { get; set; }
    public virtual SupplierSeason SupplierSeason { get; set; }

    [ForeignKey("CheckedOutById")]
    public virtual CheckOut CheckedOutBy { get; set; }
    public int? CheckedOutById { get; set; }

    public DataState DataState { get; set; }

    public virtual ICollection<CheckOut> CheckOuts { get; set; } 
    public virtual ICollection<AnalysisRevision> Revisions { get; set; }

    [ForeignKey("SourceId")]
    public virtual AnalysisSource Source { get; set; }
    public int SourceId { get; set; }
}

生成的迁移

        CreateTable(
            "dbo.CheckOut",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    ByUserId = c.Int(nullable: false),
                    AnalysisId = c.Int(nullable: false),
                    At = c.DateTime(nullable: false),
                    Analysis_Id = c.Int(), // The rogue column
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.Analysis", t => t.AnalysisId, cascadeDelete: true)
            .ForeignKey("dbo.UserProfile", t => t.ByUserId, cascadeDelete: true)
            .ForeignKey("dbo.Analysis", t => t.Analysis_Id)
            .Index(t => t.ByUserId)
            .Index(t => t.AnalysisId)
            .Index(t => t.Analysis_Id);

分析表的脚本(注意流氓Checkout_Id字段)

                 CreateTable(
            "dbo.Analysis",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Name = c.String(),
                    SupplierSeasonId = c.Int(nullable: false),
                    CheckedOutById = c.Int(),
                    DataState = c.Int(nullable: false),
                    SourceId = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.SupplierSeason", t => t.SupplierSeasonId, cascadeDelete: true)
            .ForeignKey("dbo.CheckOut", t => t.CheckedOutById)
            .ForeignKey("dbo.AnalysisSource", t => t.SourceId, cascadeDelete: true)
            .Index(t => t.SupplierSeasonId)
            .Index(t => t.CheckedOutById)
            .Index(t => t.SourceId);

1 个答案:

答案 0 :(得分:3)

实体框架正在做你告诉它做的事情。请注意,AnalysisCheckOut之间存在两种关系。

首先,您有一对一的关系,并且使用CheckedOutByIdAnalysisId存储该关系。

然后,由于CheckOuts实体中的导航属性Analysis,您也有一对多的关系,但CheckOut实体没有用于存储此关系的外键,而实体框架是为你生成一个。

我也发现了其他问题,也许你想看看:

  • 属性[ForeignKey("ByUser")]放错地方。
  • 如果您使用的是命名约定,则无需使用ForeignKey属性。
  • 在构造函数中初始化导航属性将禁用更改跟踪代理(并且我相信会抛出异常),因为您将覆盖 EF 正在为您创建的集合。

修改 您可以使用此代码使用流畅的api设置关系。我对你的代码做了一些假设,但它应该有效。在DbContext课程中使用此功能。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<CheckOut>().HasRequired(c => c.Analysis).WithOptional(a => a.CheckedOutBy);
    modelBuilder.Entity<Analysis>().HasMany(a => a.CheckOuts).WithRequired(c => c.AnalysisMany);
}