SubSonic 3.0.0.4 Обновление не хватает памяти - PullRequest
0 голосов
/ 25 февраля 2011

Когда я пытаюсь обновить много сообщений (~ 50000) с помощью SubSonic 3.0.0.4 после примерно 25000 обновлений, я получаю исключение из-за нехватки памяти. (Windows7, VS10, SQLServer2008R2)

var myTable = new SubSonicRepository<MyObject>(new MyDB());
getDataFromALargeList

foreach(post in LargeList)
{
    var myObject=GetMyObject(int myID)
    myObject.property1=..
    myObject.property2=..
    myTable.Update(myObject);
}
private MyObject GetMyObject(int myID)
{
    var myObject = new MyObject();
    var tbl = new SubSonicRepository<MyObject>(new MyDB());
    return tbl.Load(myObject, "ID", id) ? myObject : new MyObject();
}

Есть идеи?

Ответы [ 2 ]

1 голос
/ 27 февраля 2011

Я столкнулся с той же проблемой с дозвуковой 3 ActiveRecord.Быстрое исследование общего кода показало, что каждый дозвуковой объект ActiveRecord создал новый экземпляр БД, новый репозиторий и новую таблицу.Код в основном:

_db=new Northwind.Data.NorthwindDB();
_repo = new SubSonicRepository<Products>(_db);
tbl=_repo.GetTable();

Это происходит для каждого создаваемого вами экземпляра ActiveRecord.

Если вы работаете с большими наборами данных, шаблоны LinqTemplates занимают меньше памяти.Например, у меня возникла проблема с загрузкой 100000 записей

 // ActiveRecord: slow, eventually ended in a OutOfMemoryException
var query = from p in Products.All()
            select p;
var products = query.ToList();

// LinqTemplates: runs fast with at least no memory footprint
// (except for the data itself)
var db = new Northwind.Data.NorthwindDB();
var query = from p in db.Products
            select p;
var products = query.ToList();

. Паттерн ActiveRecord следует использовать с осторожностью.Он отлично подходит для извлечения одной записи из БД, обновления некоторых значений и сохранения изменений или даже для быстрого обновления нескольких записей (скажем, до 1000 записей), но для большого количества данных это не лучший выбор, посколькунакладные расходы.

В любом случае, извлечение записи из БД только для обновления значения является плохим выбором как для ActiveRecord, так и для LinqTemplates (если только у вас нет для этого веских причин, например, вы внедрили некоторую бизнес-логику в свойОбъекты DAL.)

Рассматривали ли вы просто вместо этого обновление?

db.Update<MyObject>()
    .Set(x => x.property1 == 5)
    .Set(x => x.property2 == "Hello World")
    .Where(x => x.ID == 1)
    .Execute();
0 голосов
/ 25 февраля 2011

Вам нужно будет делать обновления в пакетном режиме, если вы действительно хотите сделать это в коде приложения, поскольку ваши почтовые объекты превышают пределы выделения памяти в среде выполнения .NET.

Ваш код должен учитыватьсяобщее количество записей, которое вам нужно обработать, а затем выберите записи для обработки в пакетах, скажем, 500, пока не закончите.Таким образом, сборщик мусора может освободить память, когда ваши почтовые объекты выходят из области видимости (для каждого пакета), и вы проходите обработку всех записей.

В качестве альтернативы, это, вероятно, один из таких случаев.где стоит опуститься до необработанного SQL.Если вы делаете эти обновления часто, может быть, стоит потратить время на написание процедуры для этого внутри базы данных.

...