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

时间:2010-12-08 16:45:15

标签: sql-server-2008 c#-4.0 data-access

我有一个场景,我需要提取大约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的DataSet是最好的方法吗? ORM?

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

2 个答案:

答案 0 :(得分:0)

DECLARE CURSOR on the Entity.

OPEN CURSOR.

For each FETCH CURSOR

    SELECT the child rows for the current Entity.

    Write the output.

CLOSE CURSOR.

答案 1 :(得分:0)

所以我最终做的是拥有一个嵌套的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语句,以检索每个父项的所有子实体,而不是每个父项每个子项单独的语句。

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

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