我正在使用VS2013和Entity Framework 6.1来对抗SQL 2012。
当我使用Code First在Dev中创建我的类和表时,它工作正常。 当我通过Web Deploy发布到我的第三方主机时,所有部署都会部署,但在数据库中没有创建任何表。连接字符串/ s包含具有对数据库的表创建访问权限的用户的相应用户名和密码。 (经过测试,因为我通过SSMS使用相同的登录名/密码 在托管SQL服务器上成功创建表) 数据库发布连接字符串正在正确生成并具有正确的值。
当我使用Execute Code First Migrations复选框部署ASP.Net MVC应用程序时,该应用程序会在托管服务器上引发500错误。
对可能出现的问题有什么看法?
答案 0 :(得分:1)
听起来这是对VS Web部署功能如何处理EFCF迁移的误解。
通常(非EFCF),VS会将您的文件发布到远程服务器并更新数据库架构。部署完成后,所有更改都已应用。
通过EFCF迁移,情况并非如此。 VS的部署将修改您的web.config以设置数据库所需的连接字符串。这反映在已发布的文件中,但尚未触及数据库。在迁移代码运行之前,不会对DB进行更改。默认情况下,第一次代码初始化DbContext时会发生这种情况; DbInitializer将执行尚未应用的任何迁移。通常,这意味着您必须从您的站点请求页面才能触发此过程。
对我的评论进行一点阐述:
手动更改架构不是一个很好的解决方案,因为它会阻止迁移从以后运行(“表Foo已存在”类型错误)。
如果您对数据库进行了与迁移代码不兼容的更改,您将从EF获得异常。例如,您可能有此迁移:
public override void Up()
{
CreateTable(
"dbo.Foo",
c => new
{
Id = c.Int(nullable: false, identity: true),
Value = c.String(nullable: false, maxLength: 200),
})
.PrimaryKey(t => t.Id);
}
如果您手动创建了表Foo(例如,因为部署后没有看到它),则EF无法再应用此迁移,并抛出异常。这可能是您看到的HTTP 500错误的原因。
答案 1 :(得分:1)
出于某种原因,我必须确定已部署的Web.config中添加了EntityFramework部分,该部分不在我的本地版本的Web.config中。该错误是由EntityFramework部分引起的,但没有部分描述符指定存在EntityFramework部分。
我添加了部分描述符,一切正常。
我不确定为什么在部署内容时发生了转换,但转换不完整。
答案 2 :(得分:0)
我会在你的应用程序中设置错误页面。
在Web.config
下的<system.web>
,你会有
<customErrors mode="On" defaultRedirect="~/Error/Index">
<error statusCode="400" redirect="~/Error/Error400" />
<error statusCode="403" redirect="~/Error/Error403" />
<error statusCode="404" redirect="~/Error/Error404" />
</customErrors>
因此,defaultRedirect
会捕获500错误。
您的Error
控制器可能如下所示。
public class ErrorController : Controller
{
public ActionResult Index()
{
return View("Error");
}
public ActionResult Error400()
{
return View("Error400");
}
public ActionResult Error403()
{
return View("Error403");
}
public ActionResult Error404()
{
return View("Error404");
}
}
您的Error
视图(我在Views\Shared
目录中)看起来如下所示。
@{
Layout = "~/Views/Shared/_Layout_Blank.cshtml";
ViewBag.Title = "Application Error";
}
@model System.Web.Mvc.HandleErrorInfo
<h1>Application Error</h1>
@if (Model != null)
{
<div>
Location: @Model.ControllerName/@Model.ActionName
<br />
Message: @Model.Exception.Message
</div>
}
else
{
<div>
You've reached this page in error.
</div>
}