SubSonic 3.0.0.4 更新内存不足

发布于 2024-10-18 23:49:56 字数 599 浏览 1 评论 0原文

当我在大约 25000 次更新后尝试使用 SubSonic 3.0.0.4 更新许多帖子(~50000)时,出现内存不足的异常。 (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();
}

有什么想法吗?

When I try to update many posts (~50000) using SubSonic 3.0.0.4 after about 25000 updates i get an exception, out of memory. (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();
}

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

再见回来 2024-10-25 23:49:56

我在使用 subsonic 3 ActiveRecord 时遇到了同样的问题。
对generad代码的快速调查表明,每个亚音速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();

I encountered the same problem with subsonic 3 ActiveRecord.
A quick investigation of the generad code showed that every subsonic ActiveRecord object created a new db instance, a new Repository and a new table. The code is basically:

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

That happens for every ActiveRecord instance you create.

If you are working with large data sets the LinqTemplates are less memory consuming.
For instance I got a problem by loading 100000 records

 // 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();

You should use the ActiveRecord patten with caution.
It is great for pulling a single record from the db, update some values and persist the changes or even for fast updating multiple records (let's say up to 1000 recors) but for lage amount of data it is not the best choice, because of the overhead.

Anyway, pulling a record from the DB just to update a value is a bad choice, for both: ActiveRecord and LinqTemplates (unless you have a good reason for it, e.g. you implemented some business logic into your DAL objects.)

Have you considered just doing an update instead?

db.Update<MyObject>()
    .Set(x => x.property1 == 5)
    .Set(x => x.property2 == "Hello World")
    .Where(x => x.ID == 1)
    .Execute();
守护在此方 2024-10-25 23:49:56

如果您确实想在应用程序代码中执行此操作,则需要批量执行更新,因为您的 post 对象超出了 .NET 运行时的内存分配限制。

您的代码应该计算需要处理的记录总数,然后以 500 条为一组选择要处理的记录,直到完成。这样,当您的 post 对象超出范围(对于每个批次)并且您继续处理所有记录时,垃圾收集器可以回收内存。

或者,这可能是值得使用原始 SQL 的场合之一。如果您经常进行这些更新,那么非常值得您花时间编写一个过程来在数据库中执行此操作。

You will need to do your updates in batches if you really want to do this within your application code, because your post objects are exceeding the memory allocation limits of the .NET runtime.

Your code should count the total number of records that you need to process, and then select records for processing in batches of say 500, until done. This way, memory can be reclaimed by the garbage collector as your post objects pass out of scope (for each batch) and you progress through the processing of all the records.

Alternatively, this is probably one of those occasions where it is worth dropping down to raw SQL. If you do these updates often it could be well worth your time to write a procedure to do this inside the database.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文