使用 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]
。
工作真的很好,但又一次感觉真的很多......如果我没有进行很多数据库迁移,我会坚持我的第一个建议。
是否可以先在 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]
。
工作真的很好,但又一次感觉真的很多......如果我没有进行很多数据库迁移,我会坚持我的第一个建议。