Die Speicherung von großen Dateien in der Datenbank führt zu Einer Ausnahme des Typs 'System.OutOfMemoryException'

Habe ich eine kleine gebaut, MVC4 Webseite für den Austausch von Dateien mit den code-first-Ansatz. Die Dateien gespeichert sind, in meine Datenbank als

public byte[] Content { get; set; }

Ive set

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

und

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

Begrenzen die Dateigröße auf 500 Mb, so dass die Datei eigentlich macht es in meinen code (war fest auf dieses eine bit zuerst).

Ist das eigentliche problem passiert, wenn ich die Datei erhalten haben und versuchen, in der Datenbank speichern, ich nenne das:

DbContext.SaveChanges()

Und bekomme diese Fehlermeldung:

Eine Ausnahme des Typs " System.OutOfMemoryException " ist in
System.Data.Entity.dll wurde aber nicht behandelt werden, in Benutzer-code

Ich vermute, das ist weil ich bin zu schlagen, eine Art von limit, wie viele Daten können gespeichert werden, in ein byte[] in die DB (oder wie viel Speicher mein Prozess verwenden darf).. Alles funktioniert beim Upload kleiner Dateien.

Den Datenbank-server ist ein SQL 2008 R2 Standard server.

Ich würde es vorziehen, zu vermeiden, speichern Sie die Dateien auf der Festplatte aus Gründen der Einfachheit.. was sind meine Möglichkeiten?

EDIT: Mit dem Vorschlag zu tun, eine straight-up-SQL-Abfrage, um die Datei einfügen, hab mir letzten das erste problem, bekommen Sie die Datei in die Datenbank:

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

Aber ich bin jetzt immer der exakt gleiche Fehler beim Versuch, die Datei aus der Datenbank statt. Dies bewirkt, dass die Fehlermeldung jetzt:

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

Wieder, es funktioniert für kleinere Dateien <100 MB, aber Absturz auf 200 Mb-Dateien.

Hinzufügen stacktrace zu Frage pro Kommentar in den Antworten unten:

System.OutOfMemoryException wurde unhandled by user code

HResult=-2147024882 Meldung=Exception-Typ
'System.OutOfMemoryException " wurde ausgelöst. Source= "mscorlib"

StackTrace:
System.Objekt.MemberwiseClone()
System.Array.Clone () -
System.Daten.Common.CommandTrees.DbConstantExpression..ctor(TypeUsage
resultType, Object Wert)
System.Daten.Mapping.Update.Intern.UpdateCompiler.GenerateValueExpression(EdmProperty
Eigenschaft, PropagatorResult Wert)
System.Daten.Mapping.Update.Intern.UpdateCompiler.BuildSetClauses(DbExpressionBinding
Ziel PropagatorResult Zeile, PropagatorResult originalRow,
TableChangeProcessor Prozessor, Boolean insertMode, Wörterbuch2&
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__71
1.MoveNext()
System.Daten.Mapping.Update.Intern.UpdateCommandOrderer..ctor(IEnumerable1
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
2 Parameter)
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext
controllerContext, ActionDescriptor actionDescriptor, IDictionary2
parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8
1.b__7(IAsyncResult
)
System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.Ende()
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult
asyncResult)
bei System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c
_DisplayClass37.<>c_DisplayClass39.b_33()
System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c_DisplayClass4f.b_49()
InnerException:

Lösung:

Hier ist ein komplettes Beispiel, wie dies gelöst wurde:

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

  • blogs.msdn.com/b/ericlippert/archive/2009/06/08/...
  • Wie sieht Ihre entity-Klasse Aussehen wird und was ist der Datentyp des Felds in der sql server-Tabelle?
  • Was ist Ihre aktuelle code Aussehen..? könnten Sie möglicherweise einen Speicherverlust in den vorhandenen code..?
  • Der Datentyp in der Datenbank ist vom Datentyp varbinary(max), ich habe es definiert als byte[] in meinem Modell. DJKRAZE bezweifle ich, es ist ein Speicher-Leck, wie es geschieht bei der ersten Anforderung nach dem Start des Projektes, große Dateien immer wieder der Fehler oben
  • Haben Sie überprüft, die Maschine, die Speicherauslastung, wenn der Fehler Auftritt?
  • 4 von 8 GB frei, wenn die Fehlermeldung Auftritt,

InformationsquelleAutor JensB | 2013-01-26
Schreibe einen Kommentar