实体框架无法创建外键约束,"引用表中没有主键或候选键..."

时间:2017-01-09 18:45:16

标签: entity-framework sql-server-2008

我试图在两个模型File和AMCN之间创建一对多的关系。这是我的档案:

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

    public int AmcnId { get; set; }
    [StringLength(255)]
    public string FileName { get; set; }
    [StringLength(100)]
    public string ContentType { get; set; }
    public byte[] Content { get; set; }

    public virtual AMCN Amcn { get; set; }
}

这是我AMCN的一部分:

public class AMCN
{
    public int Id { get; set; }
    public DateTime Created { get; set; }
    //lots of other data here...
    public virtual ICollection<File> Files { get; set; }
    public virtual ICollection<FoSL> FoSLs { get; set; }
}

所以我进入了包管理器控制台,做了add-migration files,它工作并生成了这个:

public partial class files : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.Files",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    AmcnId = c.Int(nullable: false),
                    FileName = c.String(maxLength: 255),
                    ContentType = c.String(maxLength: 100),
                    Content = c.Binary(),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.AMCNs", t => t.AmcnId, cascadeDelete: true)
            .Index(t => t.AmcnId);

    }

    public override void Down()
    {
        DropForeignKey("dbo.Files", "AmcnId", "dbo.AMCNs");
        DropIndex("dbo.Files", new[] { "AmcnId" });
        DropTable("dbo.Files");
    }
}

但当我update-database时,我收到错误:

Error Number:1776,State:0,Class:16
There are no primary or candidate keys in the referenced table 'dbo.AMCNs' that match the referencing column list in the foreign key 'FK_dbo.Files_dbo.AMCNs_AmcnId'.
Could not create constraint. See previous errors.

据我所知,实体框架应该能够弄清楚我希望AmcnId是一个指向AMCN.Id的外键。事实上,当我创建另一个类FoSL时,它运行良好。

public class FoSL
{
    public int Id { get; set; }
    public int AmcnId { get; set; }
    public string FO { get; set; }
    public DateTime StartDate { get; set; }
    public string Location { get; set; }
}

生成的迁移类

public partial class FoSL : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.FoSLs",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    AmcnId = c.Int(nullable: false),
                    FO = c.String(),
                    StartDate = c.DateTime(nullable: false),
                    Location = c.String(),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.AMCNs", t => t.AmcnId, cascadeDelete: true)
            .Index(t => t.AmcnId);

    }

    public override void Down()
    {
        DropForeignKey("dbo.FoSLs", "AmcnId", "dbo.AMCNs");
        DropIndex("dbo.FoSLs", new[] { "AmcnId" });
        DropTable("dbo.FoSLs");
    }
}

我无法看到FoSLFile类或其迁移之间的任何真正差异。据我所知,这应该有效。那么我做错了什么?

我尝试在[Key]上添加AMCN.Id,没有帮助。

编辑:初始dbmigration包含此Up()

        CreateTable(
            "dbo.AMCNs",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Created = c.DateTime(nullable: false),
                    //lots of other data here....
                })
            .PrimaryKey(t => t.Id);

2 个答案:

答案 0 :(得分:0)

原来,罪魁祸首是我忘记的事情;我做了一个备份数据库进行测试,所以在我准备好之前,我不会影响生产数据库。但是,当我将数据备份到新数据库时,它没有用它来获取密钥。因此,我在数据库中的AMCN表没有实体框架期望它拥有的主键。我添加了一个主键,再次在包管理器控制台中运行update-database,它运行正常。

(不确定我是否应删除此问题......)

答案 1 :(得分:0)

发生在亚当身上的事情也发生在我身上。我创建了一个备份数据库来测试更改而不影响我的生产环境。使用 MS SSMS 上的 SQL 导入/导出向导进行复制,意味着表的 PK 信息没有被复制,因此迁移工作,但尝试更新数据库没有,因为没有明确的 PK找到了。

在 SSMS 表设计器中手动配置 PK,迁移工作完美。发帖以防有人犯和我一样的错误!