كيفية منع تجاوز الذاكرة عند استخدام IEnumerable وينق إلى SQL؟
-
06-07-2019 - |
سؤال
ويرتبط هذا السؤال إلى سؤال سابق لي
وهذا هو قانون بلدي الحالي
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();
}
}
وأنا الحصول على تجاوز الذاكرة، منذ IEnumerable كبير جدا. كيف يمكنني منع ذلك؟
المحلول
InsertOnSubmit بدلا من < وأ href = "http://msdn.microsoft.com/en-us/library/bb763476(VS.100).aspx" يختلط = "نوفولو noreferrer"> InsertAllOnSubmit . ومن ثم ارتكاب على فترات مناسبة، مثل قال إريك.
وأو، إذا كنت تريد أن تفعل ذلك على دفعات من مثل 5، في محاولة <لأ href = "https://stackoverflow.com/questions/1034429/how-to-prevent-memory-overflow-when-using-an-ienumerablet-and-linq-to-sql/1034476#answer- 1035039 "> حلول Handcraftsman في أو DTB للحصول على IEnumerable من IEnumerable. على سبيل المثال، مع القطعة DTB ل:
var actual = Get();
using (var db = new DataClassesDataContext())
{
foreach(var batch in actual.Chunk(5))
{
db.Shapes.InsertAllOnSubmit(batch);
db.SubmitChanges();
}
}
نصائح أخرى
وخيار واحد هو تقسيمها إلى دفعات متعددة. إنشاء مخزن مؤقت للكائنات Shape
، تكرار حتى يتم تعبئته أو نفد من العداد، ثم القيام InsertBatchOnSubmit
.
استخدم طريقة الإضافة التالية للخروج من المدخلات إلى مجموعات فرعية بحجم مناسب
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;
}
}
}
وبعد ذلك تستمر فرعية
void Insert()
{
var actual = Get();
using (var db = new DataClassesDataContext())
{
foreach (var set in actual.InSetsOf(5))
{
db.Shapes.InsertAllOnSubmit(set);
db.SubmitChanges();
}
}
}
وقد تجد أيضا <لأ href = "http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/994e75cb-f651-4a2a-aa4a-39de7fa2fd1b" يختلط = "نوفولو noreferrer" > هذه المقالة MSDN على InsertOnSubmit () مقابل InsertAllOnSubmit () لتكون مفيدة.
لتكتنف طريقة للحصول على دفعات من العناصر من IEnumerable، الاطلاع على:
<وأ href = "https://stackoverflow.com/questions/1008785/c-cleanest-way-to-divide-a-string-array-into-n-instances-n-items-long/1008974# 1008974 "> C #: أنظف وسيلة لتقسيم مجموعة سلسلة في حالات N N البنود طويلة
تحديث: ليس جيدا، أن يعمل على المصفوفات. إذا كان لدي وقت لاحق بعض الوقت وليس لأحد آخر قد قدمت شيئا، أنا أكتب عنه ...