【问题标题】:Define SQL table primary key as case sensitive using Entity Framework Code First使用 Entity Framework Code First 将 SQL 表主键定义为区分大小写
【发布时间】:2016-01-18 21:46:05
【问题描述】:

是否可以先在实体框架代码中定义一个区分 SQL 大小写的主键?我知道默认情况下,对于字符串,SQL 是不区分大小写的,为了清楚起见,我不想将整个数据库定义更改为区分大小写,只需一个表列(主键)。

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

理想情况下,我希望找到一种方法,通过实体框架将主键定义为区分大小写,而不是使用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来进行区分大小写的更改吗?

这是自动生成的 fluent 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

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

【问题讨论】:

标签: c# sql-server ef-code-first entity-framework-6 ef-fluent-api


【解决方案1】:

到目前为止,我得到的最好的解决方案(我绝不认为它是一个好的解决方案)是使用 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

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

解决方案 2

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 感谢您的回答,但我已经知道该选项。它在我提供的链接中。我希望 EF 有办法做到这一点,或者在没有的情况下有创造性的解决方法。
    • @LiranBo 嗯,我没有阅读链接(可能应该阅读),但是没有,没有其他方法可以做到。好吧,您可以编写自己的自定义属性,然后以某种方式挂钩到 EF,但这将是很多代码。
    猜你喜欢
    • 2015-06-25
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    相关资源
    最近更新 更多