我在SQL Server 2008上使用Entity Framework 6.1.1,我有一个长期运行的代码首次迁移(大约20分钟)。它结束然后给出以下错误。
System.Runtime.Remoting.RemotingException: Object '/f10901d8_94fe_4db4_bb9d_51cd19292b01/bq6vk4vkuz5tkri2x8nwhsln_106.rem' has been disconnected or does not exist at the server.
at System.Data.Entity.Migrations.Design.ToolingFacade.ToolLogger.Verbose(String sql)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClass30.<ExecuteStatements>b__2e()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action operation)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements, DbTransaction existingTransaction)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto)
at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
迁移的目的是更新数据库中存储某些二进制数据的MIME类型的字段。它遍历每一行,读取二进制数据,尝试确定它是什么类型的内容,然后将相应的MIME类型值写入该行。
下面的脚本使用ADO.NET生成要运行的更新语句列表。我使用ADO.NET是因为我必须使用.NET的映像库(System.Drawing.Imaging.ImageFormat)来确定每行中的二进制内容的类型(它将是jpeg,png或pdf)。
public override void Up()
{
List<string> updateStatements = new List<string>();
using(SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"]))
{
SqlCommand cmd = new SqlCommand("SELECT Table1ID, Image FROM Table1"), conn);
conn.Open();
//read each record and update the content type value based on the type of data stored
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
long idValue = Convert.ToInt64(reader["Table1ID"]);
byte[] data = (byte[])reader["Image"];
string contentType = GetMimeType(data);
updateStatements.Add(string.Format("UPDATE Table1 SET Content_Type = {0} WHERE Table1ID = {1}", contentType, idValue));
}
}
}
foreach (string updateStatement in updateStatements)
Sql(updateStatement);
}
public string GetMimeType(byte[] document)
{
if (document != null && document.Length > 0)
{
ImageFormat format = null;
try
{
MemoryStream ms = new MemoryStream(document);
Image img = Image.FromStream(ms);
format = img.RawFormat;
}
catch (Exception)
{
/* PDF documents will throw exceptions since they aren't images but you can check if it's really a PDF
* by inspecting the first four bytes with will be 0x25 0x50 0x44 0x46 ("%PDF"). */
if (document[0] == 0x25 && document[1] == 0x50 && document[2] == 0x44 && document[3] == 0x46)
return PDF;
else
return NULL;
}
if (format.Equals(ImageFormat.Jpeg))
{
return JPG;
}
else if (format.Equals(System.Drawing.Imaging.ImageFormat.Png))
{
return PNG;
}
}
return NULL;
}
我已经看过this five year old post了,它链接的文章似乎不再存在了。至少我找不到它们。
有谁知道这里发生了什么?
- 更新 -
这似乎与迁移运行的时间有关。我创建了一个除了睡眠22分钟之外什么都没做的迁移
public override void Up()
{
System.Threading.Thread.Sleep(1320000);
}
我得到了同样的错误。所以这似乎是超时的事情。我不是100%他们所指的服务器上的对象,我在这个问题上找不到太多,因为它与代码第一次迁移有关。
我尝试将迁移CommandTimeout
文件中的Configuration.cs
属性设置为5000,但它没有帮助。我还尝试将SQL Server的Remove query timeout
设置为0以防止任何超时,但它也没有帮助。
答案 0 :(得分:5)
[GitHub EntityFramework 6 Issue#96] [{https://github.com/aspnet/EntityFramework6/issues/96#issuecomment-289782427]
问题在于ToolLogger的租期(基类) MigrationsLogger是一个MarshalByRefObject)是默认值(5 分钟)。 ToolingFacade创建了记录器,它存在于 主程序的应用程序域。迁移在不同的应用程序中运行 域。如果迁移时间超过5分钟,则尝试记录 任何进一步的信息都会导致此错误。一个解决方案是 增加主程序的租约寿命。所以......主要是...... 程序,在创建ToolingFacade之前,设置租约生命周期 到更长的时间段:
using System.Runtime.Remoting.Lifetime;
...
LifetimeServices.LeaseTime = TimeSpan.FromHours(1);
答案 1 :(得分:0)
这引起了我们的头痛。问题似乎是由于EF迁移实用程序的设计。该程序创建一个新的AppDomain,用于运行迁移。新AppDomain的日志记录在原始AppDomain中处理(这就是涉及远程处理的原因)。显然,如果单个迁移花费太多时间,则记录器会获得GC。我通过用Console.WriteLine替换所有记录器调用来验证这一点 - 这使得问题消失了。可能会通过更改migrate.exe工具进行修复(但可能需要更改EntityFramework程序集本身)。
答案 2 :(得分:0)
这是Entity Framework 6中的known issue,用于需要很长时间才能完成的脚本。
一种解决方法是通过Update-Database
命令仅生成SQL脚本,然后直接在SQL Server上执行生成的SQL。为了仅生成SQL,您必须使用-Script
标志:
Update-Database -Script
答案 3 :(得分:0)
我遇到了这个问题,因为web.config中的连接字符串指向错误的服务器名称。 实际上,我必须更改c:\ windows \ system32 \ drivers \ etc \ host文件,以为此数据库主机名指定正确的IP地址。 只需确保您的数据库服务器可访问即可。