将数千条记录和数十万条子记录拉入类对象的最有效方法是什么?

发布于 2024-10-06 20:07:01 字数 688 浏览 7 评论 0原文

我有一个场景,需要提取大约 7500 条数据库记录,其中每条记录都有 6 个子实体列表。每个子列表可以是 0 到大约 125 条记录。

我的类结构看起来像这样:

public class Entity
{
    public int ID { get; set;
    public string Name { get; set; }
    public ICollection<ChildEntity1> Children1 { get; set; }
    public ICollection<ChildEntity2> Children2 { get; set; }
    public ICollection<ChildEntity3> Children3 { get; set; }
    public ICollection<ChildEntity4> Children4 { get; set; }
    ... 2 more collections
}

在检索所有实体后,我需要迭代每个实体并执行一些计算,调用一些 Web 服务和其他各种事物,并最终导出到文件。

使用 c# 4 从 MS Sql Server 2008 检索此数据的最佳策略是什么?带有 DataAdapter 的数据集是最好的方法吗? ORM?

出于显而易见的原因,我想远离选定的 N+1 场景。

I have a scenario where I need to pull approximately 7500 database records where each records has 6 child entity lists. Each of those child lists could be 0 to approximately 125 records.

My class structure kind of looks like this:

public class Entity
{
    public int ID { get; set;
    public string Name { get; set; }
    public ICollection<ChildEntity1> Children1 { get; set; }
    public ICollection<ChildEntity2> Children2 { get; set; }
    public ICollection<ChildEntity3> Children3 { get; set; }
    public ICollection<ChildEntity4> Children4 { get; set; }
    ... 2 more collections
}

After I retrieve all of the Entities, I need to iterate over each one and perform some calculations, call some web services and other various things and ultimately export to a file.

What are the best strategies for retrieving this data from MS Sql Server 2008 using c# 4? Is a DataSet with DataAdapters the best way? ORM?

I want to stay away from select N+1 scenarios for obvious reasons.

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

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

发布评论

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

评论(2

失去的东西太少 2024-10-13 20:07:01
DECLARE CURSOR on the Entity.

OPEN CURSOR.

For each FETCH CURSOR

    SELECT the child rows for the current Entity.

    Write the output.

CLOSE CURSOR.
DECLARE CURSOR on the Entity.

OPEN CURSOR.

For each FETCH CURSOR

    SELECT the child rows for the current Entity.

    Write the output.

CLOSE CURSOR.
溇涏 2024-10-13 20:07:01

所以我最终做的是有一个嵌套的 DataReader,一个外部的用于父实体获取所有父级,然后一个内部的使用 reader.NextResult() 方法在一个语句中读取所有的子级,类似于这样:

var exampleSql = "select * from child1Table; " +
                 "select * from child2Table; " +
                 "select * from child3Table"; 
                 // and so on for the other child tables
using (var outerReader = cmd.ExecuteReader())
{
    while (outerReader.Read())
    {
        var entity = new Entity();
        entity.Prop1 = outerReader[0];
        entity.Prop2 = outerReader[1];
        //.... etc.

        using (var cmdInner = new SqlCommand(exampleSql))
        using (var innerReader = cmdInner.ExecuteReader())
        {
            while (innerReader.Read())
            {
                var child = new Child1();
                child.Prop1 = innerReader[0];
                // ... etc.
                entity.Children1.Add(child);
            }
            innerReader.NextResult();
            while (innerReader.Read())
            {
                var child = new Child2();
                child.Prop1 = innerReader[0];
                // ... etc.
                entity.Children2.Add(child);
            }
            innerReader.NextResult();
            // and so on for the other child entities
        }
    }
}

至少这样,我只向数据库发送一个 sql 语句来检索每个父级的所有子实体,而不是为每个父级的每个子级发送一个单独的语句。

如果有人有更好的方法,随时告诉我。

顺便说一句,我的示例代码只是伪代码。真正的事情是使用参数化查询,不选择星号,只选择我需要的列。目的是展示方法,而不是实际实现。

So what I ended up doing was having a nested DataReader, one outer one for the parent entity to get all of the parents, and then one inner one that reads all of the children in one statement using the reader.NextResult() method similar to this:

var exampleSql = "select * from child1Table; " +
                 "select * from child2Table; " +
                 "select * from child3Table"; 
                 // and so on for the other child tables
using (var outerReader = cmd.ExecuteReader())
{
    while (outerReader.Read())
    {
        var entity = new Entity();
        entity.Prop1 = outerReader[0];
        entity.Prop2 = outerReader[1];
        //.... etc.

        using (var cmdInner = new SqlCommand(exampleSql))
        using (var innerReader = cmdInner.ExecuteReader())
        {
            while (innerReader.Read())
            {
                var child = new Child1();
                child.Prop1 = innerReader[0];
                // ... etc.
                entity.Children1.Add(child);
            }
            innerReader.NextResult();
            while (innerReader.Read())
            {
                var child = new Child2();
                child.Prop1 = innerReader[0];
                // ... etc.
                entity.Children2.Add(child);
            }
            innerReader.NextResult();
            // and so on for the other child entities
        }
    }
}

At least this way, I'm only sending one sql statement to the database to retrieve all of my child entities per parent instead of a separate statement per child per parent.

If anyone has a better way, please feel free to let me know.

Btw, my example code is just pseudo code. The real thing is using parameterized queries and no select stars, just the columns i need. The intent is to show the approach, not the actual implementation.

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