Wie Speicherüberlauf zu verhindern, wenn ein IEnumerable mit und Linq to SQL-?
-
06-07-2019 - |
Frage
Diese Frage wird im Zusammenhang href="https://stackoverflow.com/questions/1034266"> eine vorherige Frage von mir
Das ist mein aktueller Code IEnumerable<Shape> Get()
{
while(//get implementation
yield return new Shape(//...
}
void Insert()
{
var actual = Get();
using (var db = new DataClassesDataContext())
{
db.Shapes.InsertAllOnSubmit(actual);
db.SubmitChanges();
}
}
Ich erhalte einen Speicherüberlauf, da die IEnumerable zu groß ist. Wie kann ich das verhindern?
Lösung
Versuchen Sie InsertOnSubmit statt < a href = "http://msdn.microsoft.com/en-us/library/bb763476(VS.100).aspx" rel = "nofollow noreferrer"> InsertAllOnSubmit . Und dann in angemessenen Abständen zu begehen, wie Erich sagte.
Oder, wenn Sie es in den Reihen von zum Beispiel tun wollen 5, versuchen Sie Handcraftsman des oder dtb der Lösungen für das erhalten IEnumerable des von IEnumerable. Zum Beispiel mit dtb der Chunk:
var actual = Get();
using (var db = new DataClassesDataContext())
{
foreach(var batch in actual.Chunk(5))
{
db.Shapes.InsertAllOnSubmit(batch);
db.SubmitChanges();
}
}
Andere Tipps
Eine Möglichkeit ist, es zu brechen in mehrere Chargen. Erstellen Sie einen temporären Puffer von Shape
Objekte iterieren, bis Sie sie füllen oder aus dem enumerator ausgehen, tun dann eine InsertBatchOnSubmit
.
Verwenden Sie die folgende Erweiterungsmethode die Eingabe in geeigneter Größe Subsets zu brechen
public static class IEnumerableExtensions
{
public static IEnumerable<List<T>> InSetsOf<T>(this IEnumerable<T> source, int max)
{
List<T> toReturn = new List<T>();
foreach(var item in source)
{
toReturn.Add(item);
if (toReturn.Count == max)
{
yield return toReturn;
toReturn = new List<T>();
}
}
if (toReturn.Any())
{
yield return toReturn;
}
}
}
dann bestehen die Teilmengen
void Insert()
{
var actual = Get();
using (var db = new DataClassesDataContext())
{
foreach (var set in actual.InSetsOf(5))
{
db.Shapes.InsertAllOnSubmit(set);
db.SubmitChanges();
}
}
}
Sie können auch finden, dieser Artikel MSDN auf InsertOnSubmit () vs InsertAllOnSubmit () nützlich sein.
Für eine saubere Art und Weise Chargen von Gegenständen aus einem IEnumerable zu bekommen, sehen folgendermaßen aus:
C #: sauberste Weg, um ein String-Array in N Instanzen N Artikel lang
teilenUpdate: Nicht gut, die auf Arrays funktioniert. Wenn ich einige Zeit später und sonst niemand haben hat etwas zur Verfügung gestellt, ich werde es aufschreiben ...