使用 Entity Framework Code First 将 SQL table 主键定义为区分大小写

Define SQL table primary key as case sensitive using Entity Framework Code First

是否可以先在 entity framework 代码中定义 SQL 区分大小写的主键?我知道默认情况下 SQL 在字符串方面不区分大小写,只是为了清楚我不想将整个数据库定义更改为区分大小写,只有一个 table 列(主键) .

我从外部 API 获取数据,它发送的数据带有区分大小写的主键('a' 和 'A' 是不同的记录),我知道我可以修改它们并将它们以不同的方式保存在我的数据库中,但这也需要我在我的代码中的任何地方都保持一致。这绝对是可能的,但我宁愿避免它。

理想情况下,我希望找到一种方法来通过 entity framework 而不是使用 SQL queries.

将我的主键定义为区分大小写

我将不胜感激任何建议,或者更好的是简单的方法。

更新

好的,所以我几乎对这成为可能失去了希望,现在当我尝试使用另一种方法时:

public ovveride Up()
{
  // drops the existing primary key named PK_dbo.Urls
  Sql("ALTER TABLE dbo.Urls DROP CONSTRAINT [PK_dbo.Urls]");

  // change the collation
  Sql("ALTER TABLE dbo.Urls ALTER COLUMN Url VARCHAR(10) COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL");

  // re-add the primary key to the Url column
  Sql("ALTER TABLE dbo.Urls ADD CONSTRAINT [PK_dbo.ShortUrls] PRIMARY KEY (Url)");
}

我真的无法完成它,因为我对该字段有 4 个不同的约束(主键 + 3 个其他)。

我不想自己重写约束代码。那么我可以使用 fluent API 来进行区分大小写的更改吗?

这是自动生成的流畅API代码:

CreateTable(
                "dbo.Shapes",
                c => new
                    {
                        TabID = c.Int(nullable: false),
                        Lbl = c.String(nullable: false, maxLength: 128),
                        wasRemoved = c.Boolean(nullable: false),
                    })
                .PrimaryKey(t => new { t.TabID, t.Lbl })
                .ForeignKey("dbo.Tabs", t => t.TabID, cascadeDelete: true)
                .Index(t => t.TabID);

我真的很感激一个解决方案,因为我已经坚持了一段时间,现在我正在寻找最好的最坏的解决方案。

更新 2

我还找到了第二种方法,它是全自动的,在你定义了很多其他东西之后,无论如何它使用自定义数据注释。请参阅下面我的回答以获取更多信息。

Entity Framework 没有内置任何东西来执行此操作 - 它始终会使用默认排序规则创建您的数据库和列。但是,您可以在迁移Up()方法中手动运行一些SQL来修改特定列的排序规则:

Sql("ALTER TABLE yourTable ALTER COLUMN YourColumn VARCHAR(50) COLLATE Latin1_General_CS_AS");

到目前为止,我得到的最佳解决方案(我认为它绝不是一个好的解决方案)是使用 EF 生成 sql 脚本,然后在那里进行修改。

我这样做的原因是因为我要更改的值不仅是一个主键,它还涉及其他 3 个约束。

如果其他人遇到同样的情况并且只需要解决方法,您可以执行以下操作:

将 sql 脚本保存到新查询:

Update-Database -Script -SourceMigration:0

然后不要删除和添加许多约束,只需找到定义您希望区分大小写的主键的行,在我的例子中:

[Lbl] [nvarchar](128) NOT NULL

更改为:

[Lbl] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL

在你开始 运行 你的脚本之前,确保在其他表中使用它作为外键时添加 COLLATE SQL_Latin1_General_CP1_CS_AS

喜欢这个解决方案,但我只是在使用它,因为它是我的全部。如果你有更好的解决方案请post啦!

解决方案 2

我可以确认 this 也能正常工作,这有点过头了。你自己定义数据注解,这里我们定义一个自定义的[CaseSensitive]。 工作真的很好,但又一次感觉真的很多......如果我没有进行很多数据库迁移,我会坚持我的第一个建议。