열의 IDENTITY 속성을 변경합니다. 열을 삭제하고 다시 만들어야 합니다.
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; }
}
DbContext 클래스에 있는 동안 주 엔터티를 아래와 같이 정의했습니다.
HasOne(b => b.Customer).WithOne(c => c.BankAccount).HasForeignKey<BankAccount>(f => f.Id);
update-database
저는 아래의 오류를 받고 있습니다.
System.잘못된 작동예외:열의 IDENTITY 속성을 변경하려면 열을 삭제하고 다시 만들어야 합니다.
그러나 이상적으로 이 오류를 제거하지 않는 것이 좋습니다. 열, 제약 조건 및 표를 삭제하고 전체 데이터베이스도 삭제했습니다.하지만 여전히 같은 오류입니다.
저는 같은 문제에 부딪혔고, 두 가지 단계와 두 가지 마이그레이션을 통해 문제를 해결했습니다.
1단계
- ID 열을 삭제합니다.
- 에 주석을 BankAccount ID(: BankAccountId)를 합니다.
ID, 마이그레이션 및 업데이트 추가 - ID가 삭제됩니다. - 새 열을 ID로 추가합니다.
2단계
- 새로 추가된 열을 삭제하고 이전 열을 다시 추가합니다.댓글 은행 계좌 ID 및 댓글 해제 ID.
- 마이그레이션 및 업데이트를 추가합니다. 그러면 BankAccountId가 삭제되고 ID가 ID로 추가됩니다.
모델을 변경하려고 할 때 이 문제가 발생했습니다.public byte Id {get; set;}
public int Id {get; set;}
문제를 과 같은 일을 .
- 모생때 지모마제로 대상 될 때까지
Remove-Migration -Project <target_project>
관리자 - 실제 데이터베이스 삭제
- 하지 않은 : 분기에서 마이그레이션)이 하고 "" " " " " " " " (" " " " " " " " " " " " " " " ( " " " " " " " " " " " " " " 을 합니다." " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " 을 합니다.
ModelSnapshot
파일로 보관하고 분기에 붙여넣습니다(조심스럽게 보관하십시오!). - 새마레생성을 하여 새
add-migration <migration_name>
관리자 - 를 이터베트로 합니다.
update-database
관리자
제 코드가 생산 환경에 있지 않았기 때문에 이런 방법으로 해결할 수 있습니다.모델이 이미 그 안에 있다면 또 다른 복잡한 문제에 직면해야 할 수도 있습니다.
이 질문에는 두 부분으로 이루어진 답이 있습니다.
TL;DR.: EF가 당신을 위해 그것을 하도록 하라.
첫 번째: EF가 관계를 수행하도록 합니다.
간단히 말해서, ID 속성은 DB가 전용 ID 열을 관리하는 데 사용하는 것이므로 각 행을 식별하기 위해 DB 외부의 어떤 것에도 의존하지 않습니다. 따라서 bankAccount 클래스는 ID 속성을 가지려면 고유한 ID 필드가 필요합니다. 이제 EF에 회선과 같은 관계를 수행하는 방법을 수동으로 알려주려고 하면 됩니다.
HasOne(b => b.Customer).WithOne(c => c.BankAccount).HasForeignKey<BankAccount>(f => f.Id);
당신이 하는 일은 EF 자체의 내부 논리를 무시하는 것이고, 이 경우 당신은 EF에게 은행 계좌 ID가 고객을 참조하는 필드이며, 그렇지 않다고 말하고 있으므로, EF는 은행 계좌 모델의 ID 필드에서 ID를 삭제하려고 합니다.하지만 그것은 단지 당신이 은행 계좌 ID가 고객 ID와 같아야 한다고 말했기 때문입니다.일대일 관계로 무슨 말을 하시려는 건지 이해가 가는 것 같습니다만, 고객이 다른 은행 계좌를 개설하려고 하면 어떻게 됩니까?D: 대신, 당신은 그것을 유지해야 합니다.int CustomerId
필드를 입력하고 삭제합니다.Customer Customer
더 만 아니라, , 더깨뿐아둘라니만사다관때니문입것인이라는 한, 둘이기 때문입니다.Customer
Id
.
public int CustomerId { get; set; } //keep
public Customer Customer { get; set; } //delete
그러면 고객은 원하는 만큼 은행에 계좌를 개설할 수 있고, 테이블은 고통받지 않으며, EF는 무엇을 해야 할지 알게 됩니다.
그러면 적절한 외부 키가 자동으로 생성되어 마이그레이션 파일에 다음과 같이 추가됩니다.
migrationBuilder.AddForeignKey(
name: "FK_BankAccount_Customer_CustomerId",
table: "BankAccount",
column: "CustomerId",
principalTable: "Customer",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
그것은 일대일 관계를 반영할 것이고, 그것은 훌륭하고 멋질 것입니다.
자, 질문에 답하자면, 여전히 자산을 삭제하려면:
두 번째: EF가 ID 속성을 삭제하도록 합니다.
(그러나 원래 질문의 외부 키 문제를 해결하지는 못할 것입니다.
먼저 요약하자면, ID 속성을 변경하기 위해 DB 관리자(mysql, sql 서버 등)는 항상 테이블을 삭제하고 다시 만들 것을 요청합니다. 왜냐하면 해당 필드는 테이블의 중심이기 때문입니다.따라서 EF를 속여서 해결책을 찾아야 합니다.
Id 에 과다같 명이름을가진두한다번추와 같은 합니다.
duplicateId
.public class BankAccount { public int Id { get; set; } public int duplicateId { get; set; } ... }
이 속임수입니다이 사람은 속임수입니다.
은 그의수서당구다니습현했신은에업곳ed▁the다를 실행했습니다.DbContext
인터페이스에서 기본 키로 사용할 필드를 ef에 지정하는 다음 방법을 추가합니다.protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<BankAccount>().HasKey(x => new { x.duplicateId }); }
다음을 사용하여 마이그레이션 추가
$ dotnet ef migrations add ModelIdChange1
하면 이 변경되기 입니다.Up
메서드는 다음과 같이 표시되어야 합니다.protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.DropPrimaryKey( name: "PK_BankAccount", table: "BankAccountTableName"); migrationBuilder.AddColumn<int>( name: "duplicateId", table: "BankAccountTableName", type: "int", nullable: false, defaultValue: 0) .Annotation("SqlServer:Identity", "1, 1"); migrationBuilder.AddPrimaryKey( name: "PK_BankAccount", table: "BankAccountTableName", column: "duplicateId"); ... }
그런 다음 데이터베이스 업데이트를 수행합니다.
$ dotnet ef database update
(이러한 명령은 이전에 이미 사용한 구문에 따라 다를 수 있습니다.)) 원본 해야 할 , 하거나 단순히 하여 "ID", ""에서 데이터를 참조하십시오.
Id
에하다가에 합니다.duplicateId
.은 오리지널 이제오지널리널▁now▁original▁the.
Id
필드는 자유롭게 삭제하거나 업데이트할 수 있으므로 모델에서 원래 필드를 삭제하십시오.public class BankAccount { public int duplicateId { get; set; } ... }
은행 계좌 ID와 고객 ID를 연결하는 원래 명령을 강제로 실행하려는 경우 이 단계에서 명령을 실행하면 작동하지만 실행하지 마십시오.
다음을 사용하여 새 마이그레이션 추가
$ dotnet ef migrations add ModelIdChange2
그런 다음 데이터베이스 업데이트를 수행합니다.$ dotnet ef database update
의 원을삭니다합제본을 삭제합니다.Id
leave 둥과잎기잎duplicateId
기본 키로 사용합니다.은 거의 열을 을 다시 에서 변경할 수 .
duplicateId
Id
다음과 같은 Bank Account 클래스:public class BankAccount { public int Id { get; set; } ... }
그리고 합니다.
$ dotnet ef migrations add ModelIdChange3
그런 다음 데이터베이스 업데이트를 수행합니다.$ dotnet ef database update
.
이 오류는 스키마를 변경하려는 경우 이미 존재하는 테이블 또는 EF 코어가 지원하지 않지만 수동 작업이 필요한 테이블을 변경하거나 수정하려고 할 때 발생합니다.이에 대해 수행할 수 있는 작업은 다음과 같습니다.
- 이 오류를 방지하기 위해 마이그레이션 파일의 관련 코드에 주석을 달아야 합니다.
- 또는 마이그레이션 파일을 제거하고 새 파일을 만듭니다.
- 업스트림 마이그레이션을 삭제하고 마이그레이션이 새 코드를 생성하도록 합니다.
해야만 했습니다.
- 코드에서 테이블 주석을 완전히 작성합니다.
- DB에서 삭제하는 마이그레이션 실행
- 수정된 매핑으로 테이블 다시 주석 달기
- 마이그레이션 다시 실행
다 했어요.
나처럼 게으른 사람들을 위해: 당신은 나의 경우처럼 "번역"이라는 표에서 기본 키 열 "Id"의 데이터 유형을 int에서 Guid로 변경하기를 원합니다.
- 이 경우 생성된 마이그레이션은 다음과 같습니다.
migrationBuilder.AlterColumn<Guid>( name: "Id", table: "Translations", type: "uniqueidentifier", nullable: false, oldClrType: typeof(int), oldType: "int") OldAnnotation("SqlServer:Identity", "1, 1");
삭제하거나 의견을 제시할 수 있습니다.
- 업데이트 데이터베이스 오류 시스템입니다.잘못된 작업예외: 열의 IDENTITY 속성을 변경하려면 열을 삭제하고 다시 만들어야 합니다.
- 또한 기본 키 제약 조건을 먼저 삭제하지 않고는 열을 삭제할 수 없습니다.새로운 마이그레이션은
migrationBuilder.DropPrimaryKey( name: "PK_Translations", table: "Translations");
migrationBuilder.DropColumn( name: "Id", table: "Translations");
migrationBuilder.AddColumn<Guid>( name: "Id", table: "Translations", type: "uniqueidentifier", nullable: false);
마이그레이션을 되돌리려는 경우에는 아래쪽 오버라이드 방법에서 반대로 수행해야 합니다.
제 생각에는 개발 데이터베이스를 제외한 모든 항목에 대해 EF 마이그레이션을 실행하는 것은 문제가 될 수 있습니다. 이는 개체의 구조를 변경할 때 EF 마이그레이션이 작동을 완전히 거부할 수 있기 때문입니다(주 키 변경 및 외부 키 변경이 가장 자주 발생함).
여러 해 동안 저는 DB 스키마가 버전 제어에 포함되도록(EF 마이그레이션에 대한 보완) 도구를 사용해 왔습니다.데이터가 중요하지 않은 개발 데이터베이스를 변경하고 여러 마이그레이션을 생성한 다음 도구를 사용하여 이러한 마이그레이션을 DB 배포 스크립트로 롤업합니다.
여기 제가 이 경우에 무엇을 할 것인지에 대한 요약이 있습니다.
- 클래스에 를 제거.
BankAccount
- 마이그레이션 생성 및 개발 데이터베이스에 적용
- 다시를 다시 합니다.
BankAccount
입니다. - 마이그레이션 생성 및 개발 데이터베이스에 적용
- DB 비교 도구(제가 선호하는 것은 APEX SQL Diff이지만 시장에는 다른 도구도 있음)를 사용하여 두 마이그레이션을 모두 롤업하는 배포 스크립트를 생성합니다.
- 데이터가 있어야 하는 준비 환경에서 이 스크립트 테스트
- 테스트가 양호한 경우 프로덕션에 적용
실제로 코드 우선 접근 방식으로 구조를 근본적으로 변경하려는 프로덕션 데이터가 있는 경우, 한 구조에서 다른 구조로 데이터 마이그레이션을 이해하고 해결하지 않으면 결과가 좋지 않을 수 있습니다.
이 경우 SharedBalances 테이블의 이름이 Balances로 바뀌고 ID 열의 SharedBalancesId가 BalancesId로 바뀝니다. SQL 명령은 SQL Server에서 실행됩니다.migration Builder를 사용해 볼 수도 있습니다.Sql(my_sql_command_here)
마이그레이션을 생성했는데 동일한 오류가 발생했습니다.
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.
마이그레이션에서 RenameTable 명령을 설명합니다.
/*
migrationBuilder.RenameTable(
name: "SharedBalances",
newName: "Balances");
*/
마이그레이션에서 AddPrimaryKey 명령에 주석을 달습니다.
/*
migrationBuilder.DropPrimaryKey(
name: "PK_SharedBalances",
table: "Balances");
migrationBuilder.AddPrimaryKey(
name: "PK_Balances",
table: "Balances",
column: "BalanceId");
*/
마이그레이션에서 테이블 이름 DropForeignKey 명령을 업데이트합니다.
여기서부터...
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");
이제 마이그레이션이 작동합니다.다음과 같은 일이 일어났습니다.
저는 같은 문제(표에 데이터가 없는 경우)를 겪었고, 다음과 같은 방법으로 해결했습니다(적절한 방법은 아니지만 저에게는 효과가 있었습니다).
- EFCore 프로젝트에서 수동 마이그레이션을 삭제했습니다._ContextModelSnapshot 파일에서 추가된 행도 제거했습니다. (적용된 마이그레이션과 생성된 마이그레이션이 하나 있는데 적용되지 않았습니다. 오류가 발생했습니다. - 열의 IDENTITY 속성 변경, 열을 삭제하고 다시 생성해야 합니다.)
- 첫 번째 마이그레이션에서 데이터베이스에 작성된 테이블을 수동으로 삭제했습니다.
- _EFMigration 테이블의 행을 삭제했습니다.삭제할 마이그레이션과 관련된 기록입니다.
- 재실행 VS
- 추가 마이그레이션새로 만들기클린 마이그레이션
- 업데이트 - 데이터베이스
(참고: 사용하고 있습니다.Net 6(EF 6.0.5 포함)
저는 이 오류를 받았지만, 상황이 정확하게 일치하지 않습니다.저는 1대 다의 관계를 가진 2개의 모델을 가지고 있습니다.많은 관계를 가진 모델에서, 저는 외부 키 속성을 키로 표시했다는 것을 깨달았습니다. 그래서 그것은 PK와 FK, 그리고 정체성이었습니다.저는 이것을 원하지 않았습니다.
[Key] 주석을 원하는 필드로 변경하고 마이그레이션을 만들었습니다.마이그레이션을 실행할 때 이 오류가 발생했습니다.새 마이그레이션에서 AlterColumn 문을 주석하고 ID 주석을 PK 필드에 추가하여 이 문제를 해결했습니다.
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_EmailListAddresses",
table: "EmailListAddresses");
//migrationBuilder.AlterColumn<int>(
// name: "AddressId", //Property I wanted to make the new PK
// table: "EmailListAddresses", //Class/Entity Name
// type: "int",
// nullable: false,
// oldClrType: typeof(int),
// oldType: "int")
// .Annotation("SqlServer:Identity", "1, 1");
//Added annotation here
migrationBuilder.AddPrimaryKey(
name: "PK_EmailListAddresses",
table: "EmailListAddresses",
column: "AddressId").Annotation("SqlServer:Identity", "1, 1");
migrationBuilder.CreateIndex(
name: "IX_EmailListAddresses_EmailListId",
table: "EmailListAddresses",
column: "EmailListId");
}
여기서 update-database 명령어를 실행하여 원하는 대로 작동했습니다.AddressId는 PK가 되고 EmailListId는 FK로 남아 있습니다.
- 테이블에 중요한 데이터가 없습니다.
- 이름
entity.ToTable("BankAccount2")
- migration 마이행추가실션이
Add-Migration BankAccountTempChanges
-
Update-Database
- 변경합니다.
entity.ToTable("BankAccount")
- migration 마이행추가실션이
Add-Migration BankAccountOk
- 데이터베이스를 다시 업데이트합니다.
Update-Database
- 테이블에 손실되지 않을 데이터가 있습니다.
- @Hani 답변의 솔루션 적용
이 단계를 수행하십시오.
1-Sql server에서 모든 ID 열 변경을 수행하십시오(코드 첫 번째 엔티티 프레임워크에는 없음).
마이그레이션의 ID 열 변경 사항(.cs 파일) 2개 표시
3-업데이트-업데이트
을 즐기다
테이블 구성의 관계형 탐색 구성 요소를 변경할 때 비슷한 문제가 발생했습니다.WithMany
WithRequiredDependent
엔티티 프레임워크는 데이터베이스에서 아무것도 변경되지 않아야 하는 경우에도 인덱스를 삭제하고 열을 다시 생성하려고 했습니다.
이 문제를 해결하기 위해 새로운 마이그레이션을 만들지 않고도 변경 사항을 수용할 수 있는 최신 마이그레이션을 다시 접었습니다.데이터베이스에서 후 " 이 스 실 다 하 행 여 레 마 있 수 습 니 접 을 이 시 다 션 그 최 신 시 다 에 서 마 되 돌 린 그 레 이 Add-Migration
정확하게 동일한 마이그레이션 이름을 가진 최신 마이그레이션에 대한 스크립트입니다.
공용 클래스 은행 계정 {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 "기본 키 열"인 열을 삭제하거나 은행 계좌로 변경한다고 명시되어 있는 경우저도 그 작품.마이그레이션 실행!
참고: 다른 이름이 생각나는 경우 열 위에 [Key]를 추가합니다.
해결 방법으로 SQL 관리 스튜디오 또는 플랫폼에 사용 중인 프로그램을 통해 수동으로 변경합니다.그런 다음 열을 변경하려는 마이그레이션 파일에서 명령을 주석 처리합니다.
즐거운시간보내세요
이 문제를 해결하기 위해:
- 데이터베이스의 모든 테이블 삭제
- 또한 .NET에서 전체 마이그레이션 폴더를 제거해야 합니다.
- 마이그레이션 추가 명령을 다시 실행합니다.
- 그런 다음 Update-Database 명령을 실행합니다.
중요한 참고:데이터베이스에 데이터가 있는 경우 데이터베이스를 삭제하기 전에 백업해야 합니다.
저는 이란에서 온 Farhad Rezvani입니다.
언급URL : https://stackoverflow.com/questions/53408175/change-the-identity-property-of-a-column-the-column-needs-to-be-dropped-and-rec
'programing' 카테고리의 다른 글
로그인한 사용자의 vue 로그인 경로 방문 중지 (0) | 2023.06.09 |
---|---|
OEM을 사용하지 않고 Oracle에서 마지막으로 통계를 실행한 시간을 확인하는 방법 (0) | 2023.06.09 |
문자열 리터럴 앞에 "r"이 붙는 것은 무엇을 의미합니까? (0) | 2023.06.09 |
MariaDB Galera 클러스터가 대기하는 대신 교착 상태를 던진 이유는 무엇입니까? (0) | 2023.06.09 |
스트립 레이블 g 그림의 위치를 위에서 아래로 변경하시겠습니까? (0) | 2023.06.09 |