EF 6.1独特的可空指数

MrE*_*ndo 43 c# sql-server entity-framework ef-code-first

在使用Code First的EF 6.1中,您可以使用实体中的属性创建索引,或者使用以下行中的流畅API:

 Property(x => x.PropertyName)
                .IsOptional()
                .HasMaxLength(450)
                .HasColumnAnnotation("Index",
                    new IndexAnnotation(new IndexAttribute("IX_IndexName") {IsUnique = true,  }));
Run Code Online (Sandbox Code Playgroud)

是否有任何方式WHERE PropertyName IS NOT NULL可以像在SQL Server中一样以原样的方式表示脚手架(参见:https://stackoverflow.com/a/767702/52026)?

Vik*_*tev 51

我没有找到告诉EF使用where where子句的方法,但这里有一些解决方法.检查它是否适合您的情况.

  1. 安装实体框架,在app.config中定义您的DbContext,实体,conn字符串等.
  2. 启用迁移 - 在程序包管理器控制台中运行'-EnableMigration'
  3. 创建DbMigration - 在程序包管理器控制台中运行'Add-Migration MigrationName'
  4. 在ovverided Up方法中创建的DbMigration类中,运行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));
Run Code Online (Sandbox Code Playgroud)

注意:不要忘记创建降级.内部的Ovveride Down方法和使用DropIndex方法:

DropIndex(tableName, indexName);
Run Code Online (Sandbox Code Playgroud)

如果数据库中已存在可能与唯一索引约束冲突的数据,则可能还需要一些其他代码.

注意:在这里您可以使用CreateIndex方法,但我无法使用它创建正确的索引.EF只是忽略我的anonymousArguments或者我写错了.您可以自己尝试并在此处写下您的结果.语法如下:

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"
    });
Run Code Online (Sandbox Code Playgroud)

5尝试为唯一列和其他相等值添加两个具有空值的etries.

这是我的演示代码 - Pastebin

  • 如果您的表名恰好是保留字,则必须将其转义,例如`tableName ="dbo.\"User \"";``(至少对于SQL Server而言) (2认同)

Sam*_*Sam 7

在EF Core中,您可以使用fluent API中的HasFilter方法来实现所需的功能,而无需在迁移中添加自定义SQL。

builder.Entity<Table>()
    .HasIndex(x => x.PropertyName)
    .HasName("IX_IndexName")
    .HasFilter("PropertyName IS NOT NULL");
Run Code Online (Sandbox Code Playgroud)

这将产生如下迁移:

migrationBuilder.CreateIndex(
    name: "IX_IndexName",
    table: "Table",
    columns: new[] { "PropertyName" },
    filter: "PropertyName IS NOT NULL");
Run Code Online (Sandbox Code Playgroud)