Как мне контролировать глубину выборки устройства отображения данных с активной загрузкой?

StackOverflow https://stackoverflow.com/questions/1201924

Вопрос

У меня есть класс datamapper, который будет охотно загружать любое свойство, к которому не прикреплен атрибут Lazy.У меня есть два объекта: штат и страна. Страна имеет обратную связь с состоянием, поскольку она содержит список всех штатов этой страны, а штат имеет прямую связь со страной, поскольку у нее есть свойство Country, которое стремится загрузить страну, которая ему присвоено.Однако если я попытаюсь получить один из этих объектов, скажем, состояние, произойдет вот что:

  1. Состояние загружается картографом
  2. Mapper достигает желаемой страны
  3. Mapper получает страну для этого штата.
  4. Mapper загружает страну
  5. Mapper достигает активной коллекции состояний
  6. Mapper загружает список состояний и начинает отображать каждое отдельное состояние, используя кэш, где это возможно.
  7. GOTO 1 для каждого штата, загруженного в страну

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

Заранее спасибо!

Редактировать:

Хорошо, после того, как Мартин Фаулер последовал совету Мэтта Хауэлла и более глубоко изучил шаблон преобразователя данных, он действительно говорит о циклической ссылке на страницах 169 и 170.Его предложение состоит в том, чтобы использовать пустой объект, загрузить его в карту идентификации и вернуть его, тем самым останавливая рекурсивную загрузку.Я прочитал этот абзац около 1000 раз и до сих пор не понимаю, как это останавливает загрузку, и, кроме того, я не понимаю, когда и как я узнаю, когда загружать этот пустой объект в мою карту идентичности.Прошу прощения за тупость, но кажется, что это пролетает прямо над моей головой.

Еще раз спасибо.

Это было полезно?

Решение

Рассмотрите возможность загрузки объектов через репозиторий, который отслеживает, какие объекты были загружены.

Редактировать:Если вы создаете свой собственный ORM (и даже если вы этого не делаете), я настоятельно рекомендую книгу Мартина Фаулера «Шаблоны архитектуры корпоративных приложений».Я смутно припоминаю, как он говорил об этой зацикленной ситуации в книге, так что это может вам помочь.

Редактировать 2:Если на шагах 4 и 5 вашего цикла вы уже загрузили страну, нет необходимости сразу загружать ее штаты, потому что они уже должны быть загружены.Это разрывает бесконечный цикл.

Другие советы

Datamapper должен перехватывать циклические ссылки.Это отечественный преобразователь данных?

Я просто хотел опубликовать решение, которое я придумал, однако считаю, что есть много способов снять шкуру с этой кошки.

Вот мой созданный FetchDepthCounterClass:

public static class FetchDepthCounter
{
    private static Dictionary<Type, int> _DepthCounter;
    private static int _MaxDepth = 3;

    static FetchDepthCounter()
    {   
        _DepthCounter = new Dictionary<Type, int>();
    }

    public static void SetDepth(int depth)
    {
        _MaxDepth = depth;
    }

    public static void ResetCounter()
    {
        _DepthCounter.Clear();
    }

    public static bool IncrementCounter(Type entityType)
    {
        if(!_DepthCounter.ContainsKey(entityType))
        {
            _DepthCounter.Add(entityType, 0);
            return true;
        }

        if(_DepthCounter[entityType] < _MaxDepth)
        {
            ++_DepthCounter[entityType];
            return true;
        }

        return false;
    }

}

IncrementCounter возвращает логическое значение, указывающее, достигнута ли максимальная глубина выборки или нет.Я вызываю счетчик приращений как часть процесса сопоставления непосредственно перед установкой значения свойства.Сначала я определяю, что мне нужно загрузить другой объект DTO или коллекцию DTO, и передаю родитель тип и приращение к этому типу.Итак, это небольшой фрагмент кода внутри моего метода SetValue в моем преобразователе данных:

if(isDto)
{
    if (!FetchDepthCounter.IncrementCounter(property.ComponentType))
        return;
}

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top