Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/32.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
C# 如果更改列的IDENTITY属性,则需要删除并重新创建该列_C#_Asp.net_Entity Framework_Entity Framework Core_Ef Core 2.1 - Fatal编程技术网

C# 如果更改列的IDENTITY属性,则需要删除并重新创建该列

C# 如果更改列的IDENTITY属性,则需要删除并重新创建该列,c#,asp.net,entity-framework,entity-framework-core,ef-core-2.1,C#,Asp.net,Entity Framework,Entity Framework Core,Ef Core 2.1,我正在使用EF Core 2.1 这是我最初的模型定义 public class Customer //Parent { public int Id { get; set; } public string Name { get; set; } public string Email { get; set; } public BankAccount BankAccount { get; set; } } public class BankAccount

我正在使用EF Core 2.1

这是我最初的模型定义

public class Customer //Parent
{
    public int Id { get; set; }

    public string Name { get; set; }

    public string Email { get; set; }

    public BankAccount BankAccount { get; set; }

}


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

    public string Branch { get; set; }

    public string AcntNumber { get; set; }

    public DateTime CreatedDate { get; set; }

    public int CustomerId { get; set; }

    public Customer Customer { get; set; }

}
但是我意识到拥有
Id
CustomerId
两者都是开销,因为它们是一对一的关系,我可以如下更新我的银行账户模型定义

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

    public string Branch { get; set; }

    public string AcntNumber { get; set; }

    public DateTime CreatedDate { get; set; }

    public Customer Customer { get; set; }

}
HasOne(b => b.Customer).WithOne(c => c.BankAccount).HasForeignKey<BankAccount>(f => f.Id);
而在DbContext类中,主体实体的定义如下

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

    public string Branch { get; set; }

    public string AcntNumber { get; set; }

    public DateTime CreatedDate { get; set; }

    public Customer Customer { get; set; }

}
HasOne(b => b.Customer).WithOne(c => c.BankAccount).HasForeignKey<BankAccount>(f => f.Id);
HasOne(b=>b.Customer)。WithOne(c=>c.BankAccount)。HasForeignKey(f=>f.Id);
运行
更新数据库时
出现以下错误

System.InvalidOperationException:要更改列的标识属性,需要删除并重新创建该列


然而,理想情况下,我不应该只是消除这个错误,我删除了列、约束和表,然后删除了完整的数据库。但仍然是相同的错误。

当您试图更改或修改已存在的表时,会发生此错误。当您想要更改架构或已存在的表时,EF core不支持该表,但需要手动操作。以下是您可以对此采取的措施:

  • 注释迁移文件中的相关代码以避免此错误
  • 或者删除迁移文件并创建一个新文件
  • 删除上游迁移并让迁移生成新代码

当我试图将模型从
public byte Id{get;set;}
更改为
public int Id{get;set;}
时,我遇到了这个问题。 面对这个问题,我做了以下几件事:

  • 使用Package Manager控制台中的
    Remove Migration-Project
    删除所有迁移,直到创建目标模型
  • 删除实际数据库
  • 如果中间有一些尚未创建的迁移,(例如,它们来自另一个分支),复制迁移文件,也复制<代码>模型快照< /C>文件,并将它们粘贴到分支中(小心地覆盖它们)。
  • 使用Package Manager控制台中的
    add migration
    创建新迁移
  • 使用Package Manager控制台中的
    update database
    更新数据库

  • 我可以用这种方式解决它,因为我的代码不在生产环境中。如果模型已经存在,您可能不得不面对另一个复杂的问题。

    我遇到了同样的问题,我通过两个步骤和两次迁移解决了它:

    步骤1

  • 删除标识列
  • 在BankAccount中注释ID并添加一个新ID(即BankAccountId为
    标识、添加迁移和更新—这将删除id)
  • 添加一个新列作为标识 步骤2

  • 删除新添加的列,然后重新添加上一列。 注释BankAccountId和un注释ID
  • 添加迁移和更新(这会删除BankAccountId并将Id添加为标识)
  • 我猜“解决方案”比“建议删除所有迁移并重新创建它”更重要,这意味着人们从未在生产环境中工作过,好吧,我希望您已经解决了这个问题,但是,对于文档,我与您共享此链接,其中解释了您需要了解的有关密钥和如何更改密钥的所有内容(并在不删除迁移的情况下解决此问题)


    另一个选择(比我做的更好)它从上次迁移中删除主迁移的更改,并从SQL中手动删除它,在SQL中手动添加新的主迁移,并且模型如何匹配您将不会有问题。

    在我看来,对除开发数据库之外的任何对象运行EF迁移都会带来麻烦,因为您自然会受到EF mi的限制Gration有时会在更改对象的结构时断然拒绝工作(更改主键和更改外键是最常见的情况)


    多年来,我一直使用各种工具来确保版本控制中包含DB模式(补充EF迁移)。如果您的开发需要更改您的开发数据库(数据不重要),请创建多个迁移,然后使用这些工具将其汇总到DB部署脚本中

    下面是我在这种情况下的总结:-

  • 删除(注释掉)对旧类的所有引用
    BankAccount
  • 创建迁移并应用于dev数据库
  • 使用已更正的定义重新添加
    BankAccount
  • 创建迁移并应用于dev数据库
  • 使用DB比较工具(我的首选是APEX SQL Diff,但市场上还有其他工具)创建一个部署脚本,用于汇总两个迁移
  • 在您的登台环境(您应该有一些数据)上测试此脚本
  • 若测试结果良好,则应用于生产
  • 现实情况是,如果您有生产数据,您希望使用代码优先的方法从根本上改变其结构,那么它可能会给您带来糟糕的结果,除非您理解并解决从一种结构到另一种结构的数据迁移问题。

    我不得不:

  • 完全从代码中注释表
  • 运行从数据库中清除的迁移
  • 使用更正的映射再次取消对表的注释
  • 再次运行迁移

  • 完成

    在我的例子中,表SharedBalances被重命名为Balances,其标识列SharedBalancesId被重命名为BalanceId。SQL命令在SQL Server上执行。您也可以尝试migrationBuilder.SQL(此处为my_SQL_command_)

    我创建了迁移,得到了相同的错误

    使用TSQL命令重命名列和表:

    EXEC sp_RENAME 'SharedBalances.SharedBalanceId', 'BalanceId', 'COLUMN';
    
    EXEC sp_RENAME 'SharedBalances', 'Balances';
    
    -- Caution: Changing any part of an object name could break scripts and stored procedures.
    
    /*
    migrationBuilder.RenameTable(
        name: "SharedBalances",
        newName: "Balances");
    */
    
    /*
    migrationBuilder.DropPrimaryKey(
        name: "PK_SharedBalances",
        table: "Balances");
    migrationBuilder.AddPrimaryKey(
        name: "PK_Balances",
        table: "Balances",
        column: "BalanceId");
    */
    
    对迁移中的RenameTable命令进行注释:

    EXEC sp_RENAME 'SharedBalances.SharedBalanceId', 'BalanceId', 'COLUMN';
    
    EXEC sp_RENAME 'SharedBalances', 'Balances';
    
    -- Caution: Changing any part of an object name could break scripts and stored procedures.
    
    /*
    migrationBuilder.RenameTable(
        name: "SharedBalances",
        newName: "Balances");
    */
    
    /*
    migrationBuilder.DropPrimaryKey(
        name: "PK_SharedBalances",
        table: "Balances");
    migrationBuilder.AddPrimaryKey(
        name: "PK_Balances",
        table: "Balances",
        column: "BalanceId");
    */
    
    对迁移中的AddPrimaryKey命令进行注释:

    EXEC sp_RENAME 'SharedBalances.SharedBalanceId', 'BalanceId', 'COLUMN';
    
    EXEC sp_RENAME 'SharedBalances', 'Balances';
    
    -- Caution: Changing any part of an object name could break scripts and stored procedures.
    
    /*
    migrationBuilder.RenameTable(
        name: "SharedBalances",
        newName: "Balances");
    */
    
    /*
    migrationBuilder.DropPrimaryKey(
        name: "PK_SharedBalances",
        table: "Balances");
    migrationBuilder.AddPrimaryKey(
        name: "PK_Balances",
        table: "Balances",
        column: "BalanceId");
    */
    
    更新迁移中表名DropForeignKey命令的出现次数:

    EXEC sp_RENAME 'SharedBalances.SharedBalanceId', 'BalanceId', 'COLUMN';
    
    EXEC sp_RENAME 'SharedBalances', 'Balances';
    
    -- Caution: Changing any part of an object name could break scripts and stored procedures.
    
    /*
    migrationBuilder.RenameTable(
        name: "SharedBalances",
        newName: "Balances");
    */
    
    /*
    migrationBuilder.DropPrimaryKey(
        name: "PK_SharedBalances",
        table: "Balances");
    migrationBuilder.AddPrimaryKey(
        name: "PK_Balances",
        table: "Balances",
        column: "BalanceId");
    */
    
    由此

            migrationBuilder.DropForeignKey(
                name: "FK_SharedBalances_Users_OwnerUserId",
                table: "SharedBalances");
    
            migrationBuilder.DropPrimaryKey(
                name: "PK_SharedBalances",
                table: "SharedBalances");
    
    为此:

            migrationBuilder.DropForeignKey(
                name: "FK_SharedBalances_Users_OwnerUserId",
                table: "Balances");
    
            migrationBuilder.DropPrimaryKey(
                name: "PK_SharedBalances",
                table: "Balances");
    
    现在您的迁移将正常工作。事情就是这样发生的:

    EXEC sp_RENAME 'SharedBalances.SharedBalanceId', 'BalanceId', 'COLUMN';
    
    EXEC sp_RENAME 'SharedBalances', 'Balances';
    
    -- Caution: Changing any part of an object name could break scripts and stored procedures.
    
    /*
    migrationBuilder.RenameTable(
        name: "SharedBalances",
        newName: "Balances");
    */
    
    /*
    migrationBuilder.DropPrimaryKey(
        name: "PK_SharedBalances",
        table: "Balances");
    migrationBuilder.AddPrimaryKey(
        name: "PK_Balances",
        table: "Balances",
        column: "BalanceId");
    */