在数据库中存储大型文件会导致类型为“System.OutOfMemoryException”的exception

我已经构建了一个小型MVC4网站,用于使用代码优先方法共享文件。 这些文件存储在我的数据库中

public byte[] Content { get; set; } 

我设定了

      

  

要将文件大小限制为500 Mb,以便文件实际上将其放入我的代码中(先将其置于此位置)。

当我收到文件并尝试将其保存到数据库时,实际问题就出现了,我称之为:

 DbContext.SaveChanges() 

并得到此错误:

System.Data.Entity.dll中出现“System.OutOfMemoryException”类型的exception,但未在用户代码中处理

我猜这是因为我在数据库中的byte []中存储了多少数据(或者我的进程允许使用多少内存),因此我遇到了某种限制。在上传较小的文件时,一切都有效。

数据库服务器是SQL 2008 R2 Standard服务器。

为了简单起见,我宁愿避免将文件存储在磁盘上。我的选择是什么?

编辑:使用直接SQL查询插入文件的建议让我超过了将文件导入数据库的第一个问题:

 DbContext.Database.ExecuteSqlCommand( @"UPDATE FileContents SET Content = @data WHERE ID = @id", new SqlParameter("id", content.ID), new SqlParameter("data", bytearray)); 

但是,当我尝试将文件从数据库中取出时,我现在得到完全相同的错误。 这会导致错误:

 byte[] respdata = DbContext.Database.SqlQuery ("SELECT TOP 1 Content FROM FileContents WHERE ID = @id", new SqlParameter("id", filepost.File.ID)).Single(); 

同样,它适用于<100 MB的较小文件,但崩溃在200 Mb文件上。

根据以下答案中的评论添加stacktrace以进行提问:

System.OutOfMemoryException未被用户代码处理
HResult = -2147024882 Message =抛出了类型’System.OutOfMemoryException’的exception。 来源= mscorlib程序
StackTrace:位于System.Data.Mapping.Update.Uternal.UpdateCompiler的System.Data.Common.CommandTrees.DbConstantExpression..ctor(TypeUsage resultType,Object value)的System.Array.Clone()处的System.Object.MemberwiseClone()处System.Data.Mapping.Update.Internal.UpdateCompiler.BuildSetClauses(DbExpressionBinding target,PropagatorResult row,PropagatorResult originalRow,TableChangeProcessor processor,Boolean insertMode,Dictionary 2& outputIdentifiers, DbExpression& returning, Boolean& rowMustBeTouched) at System.Data.Mapping.Update.Internal.UpdateCompiler.BuildInsertCommand(PropagatorResult newRow, TableChangeProcessor processor) at System.Data.Mapping.Update.Internal.TableChangeProcessor.CompileCommands(ChangeNode changeNode, UpdateCompiler compiler) at System.Data.Mapping.Update.Internal.UpdateTranslator.d__0.MoveNext() at System.Linq.Enumerable.d__71 .GenerateValueExpression(EdmProperty属性,PropagatorResult值)at 2& outputIdentifiers, DbExpression& returning, Boolean& rowMustBeTouched) at System.Data.Mapping.Update.Internal.UpdateCompiler.BuildInsertCommand(PropagatorResult newRow, TableChangeProcessor processor) at System.Data.Mapping.Update.Internal.TableChangeProcessor.CompileCommands(ChangeNode changeNode, UpdateCompiler compiler) at System.Data.Mapping.Update.Internal.UpdateTranslator.d__0.MoveNext() at System.Linq.Enumerable.d__71 1.MoveNext()at System 1 commands, UpdateTranslator translator) at System.Data.Mapping.Update.Internal.UpdateTranslator.ProduceCommands() at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) at System.Data.Entity.Internal.InternalContext.SaveChanges() at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() at System.Data.Entity.DbContext.SaveChanges() at FilePublicator2.Controllers.FileController.Upload(String qqfile) in d:\Projects\FilePublicator2\trunk\FilePublicator2\Controllers\FileController.cs:line 115 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary .Data.Mapping.Update.Internal.UpdateCommandOrderer..ctor(IEnumerable 1 commands, UpdateTranslator translator) at System.Data.Mapping.Update.Internal.UpdateTranslator.ProduceCommands() at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) at System.Data.Entity.Internal.InternalContext.SaveChanges() at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() at System.Data.Entity.DbContext.SaveChanges() at FilePublicator2.Controllers.FileController.Upload(String qqfile) in d:\Projects\FilePublicator2\trunk\FilePublicator2\Controllers\FileController.cs:line 115 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary System.Web.Mvc.Convc上的System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext,ActionDescriptor actionDescriptor,IDictionary 2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.c__DisplayClass42.b__41() at System.Web.Mvc.Async.AsyncResultWrapper.c__DisplayClass8 lerContext controllerContext,IDictionary 2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.c__DisplayClass42.b__41() at System.Web.Mvc.Async.AsyncResultWrapper.c__DisplayClass8 上的System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()中的System.Web.Mvc.Async.AsyncResultWrapper 2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.c__DisplayClass42.b__41() at System.Web.Mvc.Async.AsyncResultWrapper.c__DisplayClass8 1.b__7(IAsyncResult ) IAsyncResult asyncResult)在System.Web.Mvc.Async.AsyncControllerActionInvoker。 c _DisplayClass37。 c_ DisplayClass39.b _33()at System.Web.Mvc.Async.AsyncControllerActionInvoker。 c_ DisplayClass4f.b _49()InnerException:

解:

以下是如何解决这个问题的完整示例:

http://www.syntaxwarriors.com/2013/stream-varbinary-data-to-and-from-mssql-using-csharp/

OutOfMemory与任何框架或数据库无关。 这意味着CLR在被要求时无法分配对象。

也许,您将数据存储在多个缓冲区中,例如HttpPostedFile中的一个,一个位于内存中的byte[] ,一个位于EF中,……这会使所需的内存量倍增。

切换到ASP.NET的流式读取和流式写入ADO.NET。 教程可用。 搜索“SQL Server UPDATE WRITE”

您可以尝试绕过entity framework并直接使用ADO.Net( System.Data.SqlClient.SqlCommand等)。