EF 6.1 고유 Nullable 인덱스
EF 6.1에서는 Code First를 사용하여 엔티티의 속성을 사용하거나 다음과 같이 유창한 API를 사용하여 인덱스를 만들 수 있습니다.
Property(x => x.PropertyName)
.IsOptional()
.HasMaxLength(450)
.HasColumnAnnotation("Index",
new IndexAnnotation(new IndexAttribute("IX_IndexName") {IsUnique = true, }));
라고 할 수 있는 방법이 있습니까?WHERE PropertyName IS NOT NULL
SQL Server에서 기본적으로 사용하는 것과 동일한 방식으로 사용할 수 있습니다(https://stackoverflow.com/a/767702/52026) 참조).
나는 EF에게 이 where 절을 사용하라고 말할 방법을 찾지 못했지만 여기 몇 가지 해결책이 있습니다.케이스에 맞는지 확인합니다.
- 엔티티 프레임워크 설치, DbContext 정의, 엔티티 정의, app.config의 연결 문자열 등.
- 마이그레이션 사용 - 패키지 관리자 콘솔 '-마이그레이션 사용'에서 실행
- DbMigration 생성 - Package Manager 콘솔 'Add-MigrationMigrationName'에서 실행
- 된 "에서 된 DbMigration
Up
메서드는 고유한 null 가능 인덱스를 만들기 위해 sql을 실행합니다.
코드:
// Add unique nullable index
string indexName = "IX_UQ_UniqueColumn";
string tableName = "dbo.ExampleClasses";
string columnName = "UniqueColumn";
Sql(string.Format(@"
CREATE UNIQUE NONCLUSTERED INDEX {0}
ON {1}({2})
WHERE {2} IS NOT NULL;",
indexName, tableName, columnName));
참고: 다운그레이드도 만드는 것을 잊지 마십시오.Down
및 DropIndex
내부 메서드:
DropIndex(tableName, indexName);
또한 데이터베이스에 고유한 인덱스 제약 조건과 충돌할 수 있는 데이터가 이미 있는 경우 추가 코드가 필요할 수 있습니다.
참고: 여기서는 CreateIndex 메서드를 사용할 수 있지만 올바른 인덱스를 만들 수 없습니다.EF는 제 익명의 주장을 무시하거나 제가 잘못 적었습니다.당신이 직접 해보고 여기에 당신의 결과와 함께 쓸 수 있습니다.구문은 다음과 같습니다.
CreateIndex(
table: "dbo.ExampleClasses",
columns: new string[] { "UniqueColumn" },
unique: true,
name: "IX_UniqueColumn",
clustered: false,
anonymousArguments: new
{
Include = new string[] { "UniqueColumn" },
Where = "UniqueColumn IS NOT NULL"
});
5 고유 열 및 기타 동일한 값에 대해 null 값을 가진 두 개의 시도를 추가합니다.
여기 내 데모 코드가 있습니다 - Pastebin
EF Core에서는 Fluent API에서 HasFilter 메서드를 사용하여 마이그레이션에 사용자 지정 SQL을 추가하지 않고도 원하는 작업을 수행할 수 있습니다.
builder.Entity<Table>()
.HasIndex(x => x.PropertyName)
.HasName("IX_IndexName")
.HasFilter("PropertyName IS NOT NULL");
이렇게 하면 다음과 같은 마이그레이션이 생성됩니다.
migrationBuilder.CreateIndex(
name: "IX_IndexName",
table: "Table",
columns: new[] { "PropertyName" },
filter: "PropertyName IS NOT NULL");
아니요, 기본적으로 할 수 없습니다.
그러나 다음을 지원하는 사용자 정의 SQL 생성기를 만들었습니다.
- 의 합니다.
ASC
또는DESC
- 를 사용할 수 있습니다.
WHERE
사용하려면 인덱스 이름만 수정해야 합니다.이름은 다음과 같이 3개의 부분으로 구분됩니다.:
부품은 다음과 같습니다.
- 인덱스 이름
- 주문 정렬
- where 절
2개의 열에 인덱스가 있는 경우 다음과 같이 하십시오.Column1
ASC
그리고.Column2
DESC
그리고 필요합니다.where
인덱스 이름은 다음과 같습니다.
var uniqueName = "UN_MyIndex:ASC,DESC:Column1 IS NOT NULL";
이렇게 간단히 사용할 수 있습니다.
Property(t => t.Column1)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute(uniqueName) { IsUnique = true, Order = 1 }));
Property(t => t.Column2)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute(uniqueName) { IsUnique = true, Order = 2 }));
러면에서 당의신.Configuration.cs
이합니다. " " " "라는 이름의 파일입니다.
SetSqlGenerator("System.Data.SqlClient", new CustomSqlServerMigrationSqlGenerator());
마지막으로 다음을 생성합니다.CustomSqlServerMigrationSqlGenerator.cs
표시된 대로 파일: 여기 코드.
Viktor의 답변을 바탕으로 자동으로 이 코드를 생성하는 솔루션을 생각해냅니다.
최종 마이그레이션 파일은 사용할 수 없습니다.CreateIndex
내가 이름 붙인 방법 말고는.CreateIndexNullable
내가 만든 이 메서드는DbMigrationEx
연장되는DbMigration
protected void CreateIndexNullable(string table, string column, string name)
{
Sql($@"CREATE UNIQUE NONCLUSTERED INDEX [{name}] ON {table}([{column}] ASC) WHERE([{column}] IS NOT NULL);");
}
마이그레이션 클래스 코드를 변경하는 방법은 무엇입니까?
인Configuration
설정한 마이그레이션 폴더에 생성된 클래스
CodeGenerator = new CSharpMigrationCodeGeneratorIndexNullable();
나의CSharpMigrationCodeGeneratorIndexNullable
클래스 확장CSharpMigrationCodeGenerator
저는 정확한 수업 내용을 보여주지 않고 아이디어만 발표하겠습니다.기준CSharpMigrationCodeGenerator
내용이 일부 메서드를 오버라이드했습니다.Entity Framework 프로젝트는 https://github.com/aspnet/EntityFramework6 에서 이용할 수 있습니다.
마이그레이션 클래스를 다음으로 변경하려면DbMigrationEx
방법을 사용했습니다.
Generate(IEnumerable<MigrationOperation> operations, string @namespace, string className)
변화가 필요한 유일한 것은
WriteClassStart(
@namespace, className, writer, "DbMigration", designer: false,
namespaces: GetNamespaces(operations));
마이그레이션 방법을 다음으로 변경하려면CreateIndexNullable
방법을 사용했습니다.
Generate(CreateIndexOperation createIndexOperation, IndentedTextWriter writer)
라인을 변경해야 합니다.
writer.Write("CreateIndex(");
또한.
WriteIndexParameters(createIndexOperation, writer);
로.
writer.Write(", ");
writer.Write(Quote(createIndexOperation.Name));
그러나 인덱스가 null이어야 하는지 여부를 어떻게 알 수 있습니까?
createIndexOperation
매개 변수에 인덱스 정보가 포함되어 있습니다.수정할 수 없습니다.CreateIndexOperation
생성, 그러나Table
,Name
그리고.Columns
속성은 엔티티 클래스의 필드로 이동하고 가져오기에 충분할 수 있습니다.Index
확장할 수 있는 속성입니다.
EF6을 사용하면 다음과 같은 비클러스터된 고유 인덱스를 수행할 수 있습니다.
modelBuilder.Entity<T>()
.HasIndex(index => index.Column, "idx_column_notnull")
.IsUnique()
.HasFilter("column IS NOT NULL")
.IsClustered(false);
언급URL : https://stackoverflow.com/questions/24361518/ef-6-1-unique-nullable-index
'programing' 카테고리의 다른 글
Mac OS 10.6 Snow Leopard에서 MySql을 시작할 수 없습니다. (0) | 2023.09.02 |
---|---|
JQuery에서 클릭한 요소를 제외한 모든 클래스를 선택하는 방법은 무엇입니까? (0) | 2023.09.02 |
MariaDB 쿼리의 잘못된 LIMIT 및 OFFSET 구문 (0) | 2023.09.02 |
레지스트리 값이 있는지 테스트 (0) | 2023.09.02 |
다른 구성 요소에서 업데이트할 때 서비스 변수 변경을 감지하려면 어떻게 해야 합니까? (0) | 2023.09.02 |