4

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

public byte[] Content { get; set; }

我已经设置

<security>
  <requestFiltering>
    <requestLimits maxAllowedContentLength="536870912" />
  </requestFiltering>
</security>

<httpRuntime targetFramework="4.5" executionTimeout="6000" maxRequestLength="524288"/>

将文件大小限制为 500 Mb,以便文件实际上将其放入我的代码中(首先被卡住了)。

当我收到文件并尝试将其保存到数据库时,实际问题正在发生,我调用:

DbContext.SaveChanges()

并得到这个错误:

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

我猜这是因为我遇到了某种限制,因为数据库中的一个字节 [] 中可以存储多少数据(或者我的进程允许使用多少内存)。上传较小的文件时一切正常。

数据库服务器是 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<Byte[]>
                            ("SELECT TOP 1 Content FROM FileContents WHERE ID = @id", 
                            new SqlParameter("id", filepost.File.ID)).Single();

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

根据以下答案中的评论将堆栈跟踪添加到问题中:

System.OutOfMemoryException 未由用户代码处理
HResult=-2147024882 消息=引发了“System.OutOfMemoryException”类型的异常。Source=mscorlib
StackTrace:在 System.Object.MemberwiseClone() 在 System.Array.Clone() 在 System.Data.Common.CommandTrees.DbConstantExpression..ctor(TypeUsage resultType, Object value) 在 System.Data.Mapping.Update。 Internal.UpdateCompiler.GenerateValueExpression(EdmProperty 属性,PropagatorResult 值)在 System.Data.Mapping.Update.Internal.UpdateCompiler.BuildSetClauses(DbExpressionBinding 目标,PropagatorResult 行,PropagatorResult originalRow,TableChangeProcessor 处理器,布尔插入模式,字典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.<ProduceDynamicCommands>d__0.MoveNext() at System.Linq.Enumerable.<ConcatIterator>d__711.MoveNext() 在 System.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, IDictionary2 参数) 在 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary 2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass81.b__7(IAsyncResult ) 在System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End() 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c _DisplayClass37.< >c_ DisplayClass39.b _33() 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c_ DisplayClass4f.b _49() InnerException:

解决方案:

这是如何解决此问题的完整示例:

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

4

2 回答 2

8

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

可能,您将数据放在多个缓冲区中,例如一个 in an HttpPostedFile、一个 in-memory byte[]、一个在 EF 中,......这会成倍增加所需的内存量。

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

于 2013-01-26T23:40:21.607 回答
2

您可以尝试绕过实体框架并System.Data.SqlClient.SqlCommand直接使用 ADO.Net(等)。

于 2013-01-26T22:20:33.583 回答