M K*_* II 5 entity-framework-6
我正在尝试将我的代码第一个ID列从"int"更改为"Guid",并且在尝试运行迁移时,我收到消息:
Identity column 'CustomFieldId' must be of data type int, bigint, smallint, tinyint, or decimal or numeric with a scale of 0, and constrained to be nonnullable.
Run Code Online (Sandbox Code Playgroud)
我正在定义这样的列:
public partial class CustomField : BaseEntity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid CustomFieldId { get; set; }
Run Code Online (Sandbox Code Playgroud)
在CustomFieldMapping.cs中映射它,如下所示:
public CustomFieldMapping()
{
//Primary key
HasKey(t => t.CustomFieldId);
//Constraints
Property(t => t.CustomFieldId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Run Code Online (Sandbox Code Playgroud)
并且生成的迁移正在尝试执行此操作:
public override void Up()
{
DropForeignKey("dbo.CustomField", "CustomFormId", "dbo.CustomForm");
DropForeignKey("dbo.CustomData", "CustomFieldId", "dbo.CustomField");
DropForeignKey("dbo.CustomForm", "ParentFormId", "dbo.CustomForm");
DropIndex("dbo.CustomField", new[] { "CustomFormId" });
DropIndex("dbo.CustomForm", new[] { "ParentFormId" });
DropIndex("dbo.CustomData", new[] { "CustomFieldId" });
DropPrimaryKey("dbo.CustomField");
DropPrimaryKey("dbo.CustomForm");
AlterColumn("dbo.CustomField", "CustomFieldId", c => c.Guid(nullable: false));
AlterColumn("dbo.CustomField", "SortOrder", c => c.Int(nullable: false));
AlterColumn("dbo.CustomForm", "CustomFormId", c => c.Guid(nullable: false));
AlterColumn("dbo.CustomForm", "ParentFormId", c => c.Guid());
AddPrimaryKey("dbo.CustomField", "CustomFieldId");
AddPrimaryKey("dbo.CustomForm", "CustomFormId");
CreateIndex("dbo.CustomField", "CustomForm_CustomFormId");
CreateIndex("dbo.CustomForm", "ParentFormId");
CreateIndex("dbo.CustomData", "CustomField_CustomFieldId");
AddForeignKey("dbo.CustomField", "CustomForm_CustomFormId", "dbo.CustomForm", "CustomFormId");
AddForeignKey("dbo.CustomData", "CustomField_CustomFieldId", "dbo.CustomField", "CustomFieldId");
AddForeignKey("dbo.CustomForm", "ParentFormId", "dbo.CustomForm", "CustomFormId");
Run Code Online (Sandbox Code Playgroud)
我希望它是一个顺序递增的Guid.我究竟做错了什么?
为了解决这个问题,我在迁移类的Sql()
方法Up()
和Down()
方法中使用了一个方法.该Up()
方法中的SQL命令字符串删除ID列上的主键约束,删除类型的ID列,int
然后添加具有类型的新ID列Guid
.该Down()
方法执行相同的操作但删除Guid
列并添加新int
列.
我在Stack Overflow上找到了一些解决方案,通过在查询窗口中运行SQL命令来解决"更改列类型".解决你的评论:
我们只是试图保持一个干净/清晰的迁移路径来跟踪我们做什么,这对于SQL来说并不总是那么容易.
我在Up()
和Down()
迁移方法中使用了SQL命令.对我来说,这个解决方案适用于我的项目.
这个答案底部的解决方案是从几个Stack Overflow问题/答案中构建的.仅针对代码跳到那个.以下是冗长的细节.
我找不到像AlterColumn()
(DropColumn()
仅)那样使用Entity Framework迁移方法的解决方案.
Sql()
我没有在方法中混合使用迁移方法和命令,而是使用了迁移方法中字符串中的所有SQL命令Sql()
.使用所有SQL命令可以更轻松地在Visual Studio或SQL Server Management Studio的查询窗口中进行测试.
'Uchitha' 的答案给出了Sql()
在所需迁移类中添加"方法"的开始步骤.
Sql()
答案中的方法示例如下:
Sql("UPDATE dbo.YourTable SET Column1 = 'VALUE1' ");
Run Code Online (Sandbox Code Playgroud)
我使用'JustAnotherUserYouMayKnow' 的答案来开始更改列类型的步骤.我没有明确地遵循这个,但它只提供了删除列并重新创建它的基本框架.
Sql()
使用update语句从原始列接管数据来自'Icarus' 的答案提供了ALTER TABLE语句,用于newsequentialid()
根据您的语句生成顺序GUID:
我希望它是一个顺序递增的Guid.
ALTER TABLE your_table
ADD your_column UNIQUEIDENTIFIER DEFAULT newsequentialid() NOT null
Run Code Online (Sandbox Code Playgroud)
请注意'Icarus'在答案的评论部分中'Johan'的隐私问题:
如果隐私是一个问题,请不要使用
newsequentialid()
.可以猜测下一个生成的GUID的值,因此可以访问与该GUID相关联的访问数据
要更改的列是ID列,您已将其设置为主键.因此,在删除现有ID列之前,您需要使用另一个ALTER TABLE
SQL命令删除主键.
请参阅"darnir"中的选定答案,了解"如何使用SQL语法更改主键约束?"
ALTER TABLE <Table_Name>
DROP CONSTRAINT <constraint_name>
ALTER TABLE <Table_Name>
ADD CONSTRAINT <constraint_name> PRIMARY KEY (<Column1>,<Column2>)
Run Code Online (Sandbox Code Playgroud)
请参阅'Oleg'的注释,以确定这是否是一个因素:
PRIMARY KEY CONSTRAINT无法更改,您只能删除它并重新创建.对于大型数据集,它可能会导致运行时间过长,从而导致表不可用.
DROP CONSTRAINT
执行上面的命令时遇到问题.结果窗格列出了自动生成的约束,即使我在ALTER TABLE ... ADD COLUMN
命令中使用了特定的约束名称.请参阅此问题 "为什么SQL会继续创建DF约束?" 这个问题,如果你遇到类似的东西.
为了解决删除约束的问题,我在这个问题中使用了"ScubaSteve"的答案:"如何在不知道其名称的情况下删除SQL默认约束?" 通过'Seven'添加注释,这里是SQL命令:
DECLARE @ObjectName NVARCHAR(100)
SELECT @ObjectName = OBJECT_NAME([default_object_id]) FROM SYS.COLUMNS
WHERE [object_id] = OBJECT_ID('[tableSchema].[tableName]') AND [name] = 'columnName';
IF @ObjectName IS NOT NULL EXEC('ALTER TABLE [tableSchema].[tableName] DROP CONSTRAINT ' + @ObjectName)
Run Code Online (Sandbox Code Playgroud)
'ScubaSteve的答案中'Seven'的评论.我添加了'if'条件,因为当没有找到约束时,EXEC会失败.
要
IF @ObjectName IS NOT NULL
在EXEC命令之前添加此脚本幂等
确保在下面的代码中替换MyTableName
,MyColumnName
和dbo
,分别为您的表名,列名(例如,将列名设置为Id
)和表模式.
public override void Up()
{
Sql(@"
DECLARE @ObjectName NVARCHAR(100)
SELECT @ObjectName = OBJECT_NAME([default_object_id]) FROM SYS.COLUMNS
WHERE [object_id] = OBJECT_ID('[dbo].[MyTableName]') AND [name] = 'MyColumnName';
IF @ObjectName IS NOT NULL EXEC('ALTER TABLE [dbo].[MyTableName] DROP CONSTRAINT ' + @ObjectName)
ALTER TABLE dbo.MyTableName DROP CONSTRAINT PK_MyTableName, COLUMN MyColumnName
ALTER TABLE dbo.MyTableName
ADD Id UNIQUEIDENTIFIER DEFAULT (newsequentialid()) NOT NULL
CONSTRAINT PK_MyTableName
PRIMARY KEY CLUSTERED ([MyColumnName])
");
}
public override void Down()
{
Sql(@"
DECLARE @ObjectName NVARCHAR(100)
SELECT @ObjectName = OBJECT_NAME([default_object_id]) FROM SYS.COLUMNS
WHERE [object_id] = OBJECT_ID('[dbo].[MyTableName]') AND [name] = 'MyColumnName';
IF @ObjectName IS NOT NULL EXEC('ALTER TABLE [dbo].[MyTableName] DROP CONSTRAINT ' + @ObjectName)
ALTER TABLE dbo.MyTableName DROP CONSTRAINT PK_MyTableName, COLUMN Id
ALTER TABLE MyTableName
ADD MyColumnName int IDENTITY(1, 1) NOT NULL
CONSTRAINT PK_MyTableName
PRIMARY KEY CLUSTERED ([MyColumnName] ASC)
");
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4559 次 |
最近记录: |