Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql EF迁移正在删除一列并尝试将不存在的列重命名回Id_Sql_Entity Framework_Code First_Ef Model Builder - Fatal编程技术网

Sql EF迁移正在删除一列并尝试将不存在的列重命名回Id

Sql EF迁移正在删除一列并尝试将不存在的列重命名回Id,sql,entity-framework,code-first,ef-model-builder,Sql,Entity Framework,Code First,Ef Model Builder,我有一个使用EF的代码优先的MVC项目 有两个表,TableA和TableB,它们当前具有一对多关系: public partial class TableA { public TableA() { TableBs = new HashSet<TableB>(); } public int Id { get; set; } public Virtual ICollection<TableB> TableBs {

我有一个使用EF的代码优先的MVC项目

有两个表,
TableA
TableB
,它们当前具有一对多关系:

public partial class TableA
{ 
    public TableA()
    {
        TableBs = new HashSet<TableB>();
    }

    public int Id { get; set; }
    public Virtual ICollection<TableB> TableBs { get; set; }
}

public partial class TableB
{
    public int Id { get; set; }
    public int TableAId { get; set; }
    public virtual TableA TableAs { get; set; }
}
public partial class TableA
{ 
    public TableA() { }

    public int Id { get; set; }
    public int? TableBId { get; set; }
    public virtual TableB TableB { get; set; }
}
TableB
保持不变,我在modelcreating上更改了我的
,如下所示:

    modelBuilder.Entity<TableA>()
        .HasOptional(e => e.TableBs);

    modelBuilder.Entity<TableB>()
        .HasRequired(e => e.TableAs);

我不明白为什么它试图重命名一个不存在的列,我的新FKs在哪里?

一些事情可能会导致您的问题:

  • fluent API调用描述关系

    modelBuilder.Entity()
    .has可选(e=>e.TableBs);
    modelBuilder.Entity()
    .has必需(e=>e.tables);
    
    因为您在这里使用了两个引用不同属性的单独调用,所以我认为EF有可能将其解释为两个单独的关系。另一方面,既然他们都是一对一,那就没问题了。在任何情况下,这都更有意义,因为:

    modelBuilder.Entity<TableA>()
       .HasOptional(e => e.TableBs)
       .WithRequired(t => t.TableAs);
    
    modelBuilder.Entity()
    .has可选(e=>e.tables)
    .需要(t=>t.表格);
    
  • 实体之间的任何一种一对一关系都要求两种实体类型共享一个主键(其中依赖方/可选方的主键也是外键),这是生成的迁移混乱的主要原因

  • 我认为您也可能在过去尝试过运行迁移,在
    dbo.TableA
    中创建了列
    TableBId


  • 根据jjj所说的,我的关系有一个严重的问题,我希望正常迁移可以解决它,但jjj是正确的依赖表的FK和PK必须相同。我使用的是运行在Azure上的SQL server,因此我无法删除列
    TableB.Id
    并将
    TableB.TableAId
    重命名为
    TableB.Id
    ,因为它给了我一个聚集索引错误。他是对的,我的down语句没有drop列,所以我的
    TableBId
    仍然在
    dbo.TableA
    中。我将数据库回滚了大约5次迁移。我对
    表A的修订符合以下要求:

    public partial class TableA
    { 
    
      public int Id { get; set; }
      public int? TableBId { get; set; }
      public virtual TableB TableB { get; set; }
    }
    
    但是问题在于
    TableB
    我不得不从模型中删除
    TableAId
    我在sudo代码中添加了列,只是为了让迁移更具可读性:

    public partial class TableB
    {
      public int Id { get; set; }
      public int Column1 { get; set; }
      public int Column2 { get; set; }
      public int Column3 { get; set; }
      public virtual TableA TableAs { get; set; }
    }
    
    现在在我的背景下,我用了一句话:

    modelBuilder.Entity<TableB>()
                .HasRequired(e => e.TableA).WithOptional(x => x.TableB);
    
    这可能在其他版本的SQL中起作用,但在Azure上不起作用,因为据我所知,它不允许堆表。下面是我如何更改迁移代码的

    public override void Up()
        {
          <-- I am renaming TableB to TableB_Old just for the migration-->
         RenameTable(name: "dbo.TableB", newName: "TableB_Old");
            DropForeignKey("dbo.TableB", "TableAId", "dbo.TableA");
            DropIndex("dbo.TableB_Old", new[] { "TableAId" });
            AlterColumn("dbo.TableB_Old", "TableAId", c => c.Int(nullable: false));
    <-- Create a new TableB with the correct layout notice TableAId is not in the column list, so this still matches up to my code model-->
            CreateTable(
               "dbo.TableB",
               c => new
               {
                   Id = c.Int(nullable: false)
                   Column1 = c.Int(nullable: false)
                   Column2 = c.Int(nullable: false)
                   Column3 = c.Int(nullable: false)
               })
               .PrimaryKey(t => t.Id)
               .ForeignKey("dbo.TableA", t => t.Id)
               .Index(t => t.Id);
    
            AddColumn("dbo.TableA", "TableBId", c => c.Int());
    <-- This pulls the data from tableB_Old into the newly created TableB, since    TableA had a one-to-many relationship I had to get rid of duplicates this gets  the first record with TableAId and discards the rest. -->
    
    Sql("INSERT INTO [dbo].[TableB] (Id,Column1,Column2,Column3) SELECT     TableAId,,Column1,Column2,Column3 FROM [dbo].[TableB_Old] where [Id] In (select min([Id]) from[dbo].[TableB_Old] as T2 where T2.TableAId = [dbo].[TableB_Old].TableAId)");
    
    <--Now that we pulled all column data we needed from `TableB_Old` we can populate `TableA.TableBId`-->
    
    Sql("UPDATE [TableA] SET [TableBId] = (SELECT [Id] FROM [TableB] WHERE [TableB].[Id] = [TableA].[Id])");
    
    <-- `TableB_Old` was a good table, but it has out lived it's usefullness, it must be removed -->
    
    
            DropTable("dbo.TableB_Old");
    
    public override void Up()
    {
    重命名表(名称:“dbo.TableB”,新名称:“TableB_Old”);
    DropForeignKey(“dbo.TableB”、“TableAId”、“dbo.TableA”);
    DropIndex(“dbo.TableB_Old”,new[]{“TableAId”});
    AlterColumn(“dbo.TableB_Old”,“TableAId”,c=>c.Int(可空:false));
    创建表(
    “dbo.TableB”,
    c=>新的
    {
    Id=c.Int(可为空:false)
    Column1=c.Int(可空:false)
    Column2=c.Int(可空:false)
    Column3=c.Int(可空:false)
    })
    .PrimaryKey(t=>t.Id)
    .ForeignKey(“dbo.TableA”,t=>t.Id)
    .指数(t=>t.Id);
    AddColumn(“dbo.TableA”,“TableBId”,c=>c.Int());
    Sql(“插入[dbo].[TableB](Id,Column1,Column2,Column3)从[dbo].[TableB_Old]中选择TableAId,Column1,Column2,Column3,其中[Id]在[dbo].[TableB_Old]中选择min([Id])。[TableB_Old]作为T2,其中T2.TableAId=[dbo].[TableB_Old].TableAId]);
    Sql(“更新[TableA]设置[TableBId]=(从[TableB]中选择[Id],其中[TableB].[Id]=[TableA].[Id])”;
    
    我认为#2是解决这一问题的关键。如果我从TableB中删除ID并将TableB的主键设置为TableAID列,它看起来应该可以工作。@Landy我遇到了与您完全相同的问题,并且与您的注释有完全相同的推理。我尝试过,但实体框架仍然使用伪
    重命名生成迁移Column()
    :(.您成功地使它工作了吗?我确实使用下面的代码使它工作了,但从那时起,我还意识到不需要在TableA上使用公共int?TableBId{get;set;},因为TableB将具有与TableA相同的Id
    public partial class TableB
    {
      public int Id { get; set; }
      public int Column1 { get; set; }
      public int Column2 { get; set; }
      public int Column3 { get; set; }
      public virtual TableA TableAs { get; set; }
    }
    
    modelBuilder.Entity<TableB>()
                .HasRequired(e => e.TableA).WithOptional(x => x.TableB);
    
         public override void Up()
        {
            DropForeignKey("dbo.TableB", "TableAId", "dbo.TableAId");
            DropIndex("dbo.TableB", new[] { "TableAId" });
            DropColumn("dbo.TableB", "Id");
            RenameColumn(table: "dbo.TableB", name: "TableAId", newName: "Id");
            DropPrimaryKey("dbo.TableB");
            AddColumn("dbo.Tenants", "TableBId", c => c.Int());
            AlterColumn("dbo.TableB", "Id", c => c.Int(nullable: false));
            AlterColumn("dbo.TableB", "Id", c => c.Int(nullable: false));
            AddPrimaryKey("dbo.TableB", "Id");
            CreateIndex("dbo.TableB", "Id");
            AddForeignKey("dbo.TableB", "Id", "dbo.TableA", "Id");
        }
    
    public override void Up()
        {
          <-- I am renaming TableB to TableB_Old just for the migration-->
         RenameTable(name: "dbo.TableB", newName: "TableB_Old");
            DropForeignKey("dbo.TableB", "TableAId", "dbo.TableA");
            DropIndex("dbo.TableB_Old", new[] { "TableAId" });
            AlterColumn("dbo.TableB_Old", "TableAId", c => c.Int(nullable: false));
    <-- Create a new TableB with the correct layout notice TableAId is not in the column list, so this still matches up to my code model-->
            CreateTable(
               "dbo.TableB",
               c => new
               {
                   Id = c.Int(nullable: false)
                   Column1 = c.Int(nullable: false)
                   Column2 = c.Int(nullable: false)
                   Column3 = c.Int(nullable: false)
               })
               .PrimaryKey(t => t.Id)
               .ForeignKey("dbo.TableA", t => t.Id)
               .Index(t => t.Id);
    
            AddColumn("dbo.TableA", "TableBId", c => c.Int());
    <-- This pulls the data from tableB_Old into the newly created TableB, since    TableA had a one-to-many relationship I had to get rid of duplicates this gets  the first record with TableAId and discards the rest. -->
    
    Sql("INSERT INTO [dbo].[TableB] (Id,Column1,Column2,Column3) SELECT     TableAId,,Column1,Column2,Column3 FROM [dbo].[TableB_Old] where [Id] In (select min([Id]) from[dbo].[TableB_Old] as T2 where T2.TableAId = [dbo].[TableB_Old].TableAId)");
    
    <--Now that we pulled all column data we needed from `TableB_Old` we can populate `TableA.TableBId`-->
    
    Sql("UPDATE [TableA] SET [TableBId] = (SELECT [Id] FROM [TableB] WHERE [TableB].[Id] = [TableA].[Id])");
    
    <-- `TableB_Old` was a good table, but it has out lived it's usefullness, it must be removed -->
    
    
            DropTable("dbo.TableB_Old");