Shi*_*mar 4 entity-framework ef-migrations entity-framework-5
我必须通过Entity Framework 5使用以下模型创建数据库:
public class Post
{
public int PostId { get; set; }
[MaxLength(200)]
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我添加了新的属性 Post
public string Abstract { get; set; }
Run Code Online (Sandbox Code Playgroud)
然后我跑了
Add-Migration AddPostAbstract
Run Code Online (Sandbox Code Playgroud)
在我的Migrations文件夹中创建了以下类,之后我通过添加一个SQL语句修改了这个文件
//201308300714477_AddPostAbstract.cs
public override void Up()
{
AddColumn("dbo.Posts", "Abstract", c => c.String());
Sql("UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL");
}
public override void Down()
{
DropColumn("dbo.Posts", "Abstract");
}
Run Code Online (Sandbox Code Playgroud)
之后我执行了这个命令
Update-Database –Verbose
Run Code Online (Sandbox Code Playgroud)
它更新了我的数据库并返回了这个SQL查询:
ALTER TABLE [dbo].[Posts] ADD [Abstract] [nvarchar](max)
UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL
Run Code Online (Sandbox Code Playgroud)
现在我Abstract已从表中删除了列,并尝试在SQL中手动执行上述查询,此时它向我显示以下错误.
消息207,级别16,状态1,行2
无效的列名称"抽象".
我的问题是为什么这个查询不在SQL中执行,即使这个查询是通过迁移生成的?
或者有没有办法通过迁移生成的脚本运行这样的多个查询.
And*_*own 12
该-Verbose输出只显示发言摘要.如果在SQL Server Management Studio中手动运行命令,则需要GO在两个语句之间:
ALTER TABLE [dbo].[Posts] ADD [Abstract] [nvarchar](max)
GO
UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL
Run Code Online (Sandbox Code Playgroud)
快速解决方法是执行以下操作:
^{:b*}{{INSERT|UPDATE|SELECT|DELETE}.+}(此发现任何CRUD语句)\1GO\n\1\2\n(保持缩进,并添加GO之前的任何CRUD语句)但是,请注意,-Verbose它不会提供您想要的输出,您需要输出-Script,或者您将丢失__MigrationHistory历史表的插入数据,这可能导致应用程序在运行时抛出错误(有关详细信息,请参见下文) .
细节
您对以下有关MSDN Code First Migrations页面上的信息的评论很有意思.页面实际指出(在"获取SQL脚本"部分下)
运行Update-Database命令,但这次指定-Script标志
如果你这样做,你会看到类似的东西:
ALTER TABLE [dbo].[Posts] ADD [Abstract] [nvarchar](max)
UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL
INSERT INTO [__MigrationHistory] ([MigrationId], [Model], [ProductVersion]) VALUES ( ...
Run Code Online (Sandbox Code Playgroud)
这INSERT很重要 - 这就是您的应用程序中的EF将如何知道它使用最新的db版本(因此将运行而不是向您显示错误).但是,仍然缺少GO命令.因此,SQL Server尝试将3行编译为单个批处理并失败.
添加所需的GO语句后,您仍然可以通过以下方式将其包含在单个事务中:
BEGIN TRANSACTION;
BEGIN TRY
--Your migration code, with GO statements
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO
Run Code Online (Sandbox Code Playgroud)
如果您因为生成大型脚本而感到沮丧,那么在SSMS中放置GO任何ALTER TABLE行的末尾都是微不足道的,这将类似于此答案顶部的那个
| 归档时间: |
|
| 查看次数: |
8732 次 |
| 最近记录: |