Как наиболее эффективно вывести тысячи записей с сотнями тысяч дочерних записей в объекты класса? - PullRequest
2 голосов
/ 08 декабря 2010

У меня есть сценарий, в котором мне нужно получить примерно 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
}

После того, как я получу все сущности, мне нужно выполнить итерациюкаждый из них и выполнить некоторые вычисления, вызвать некоторые веб-службы и другие различные вещи и в конечном итоге экспортировать в файл.

Каковы наилучшие стратегии для получения этих данных из MS Sql Server 2008 с использованием c # 4?Является ли DataSet с DataAdapters лучшим способом?ORM?

Я хочу остаться в стороне от выбранных сценариев N + 1 по понятным причинам.

Ответы [ 2 ]

0 голосов
/ 09 декабря 2010

Так что я закончил тем, что имел вложенный 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-инструкцию в базу данных, чтобы извлечь все мои дочерние сущности для каждого родителя вместо отдельной инструкции для каждого дочернего элемента для родителя.

Если у кого-то есть лучший способ, , пожалуйста, , не стесняйтесь, дайте мне знать.

Кстати, мой пример кода - просто псевдокод.Реальная вещь - это использование параметризованных запросов и отсутствие выбранных звездочек, только нужные мне столбцы.Намерение состоит в том, чтобы показать подход, а не фактическую реализацию.

0 голосов
/ 08 декабря 2010
DECLARE CURSOR on the Entity.

OPEN CURSOR.

For each FETCH CURSOR

    SELECT the child rows for the current Entity.

    Write the output.

CLOSE CURSOR.
...