Вопрос

Проект, над которым я работаю, использует n-уровневую архитектуру.Наши слои следующие:

  • Доступ к данным
  • Бизнес-логика
  • Хозяйствующие субъекты
  • Презентация

Бизнес-логика переходит на уровень доступа к данным, а уровень представления переходит на уровень бизнес-логики, и все они ссылаются на бизнес-объекты.

Наши бизнес-структуры в основном соответствуют нашей модели данных 1-1.Для каждой таблицы у нас есть класс.Первоначально, когда разрабатывалась платформа, не учитывалось управление отношениями "мастер-деталь" или "потомок-родитель".Таким образом, вся бизнес-логика, доступ к данным и бизнес-объекты ссылались только на одну таблицу в базе данных.Как только мы начали разрабатывать приложение, быстро стало очевидно, что отсутствие этих взаимосвязей в нашей объектной модели серьезно вредит нам.

Все ваши слои (включая базу данных) генерируются из собственной базы метаданных, которую мы используем для управления нашим самодельным генератором кода.

Вопрос в том, каков наилучший способ загрузки или отложенной загрузки отношений в наших сущностях.Например, предположим, что у нас есть класс person, который имеет отношение master-child к таблице адресов.Это отображается в бизнес-объекте как свойство сбора адресов в объекте Person.Если у нас есть отношение "один к одному", то это будет отображаться как свойство единой сущности.Каков наилучший подход для заполнения и сохранения объектов отношений?Наши бизнес-объекты не имеют представления о уровне бизнес-логики, поэтому это не может быть сделано внутренне при вызове свойства get .

Я уверен, что для этого существует какая-то стандартная скороговорка.Есть какие-нибудь предложения?

Кроме того, одно предостережение заключается в том, что уровень DataAcess использует отражение для построения наших сущностей.Хранимые процедуры возвращают один результат selt на основе одной таблицы, и с помощью отражения мы заполняем наш бизнес-объект, сопоставляя имена свойств с именами столбцов.Так что выполнять объединения было бы сложно.

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

Решение

Я настоятельно рекомендую заглянуть в Fowler's Шаблоны корпоративной архитектуры книга.Есть несколько различных подходов к решению такого рода проблем, которые он хорошо описывает, включая отношения между сущностями.

Одним из наиболее привлекательных элементов был бы шаблон Unit Of Work, который в основном является сборщиком, который наблюдает за действиями, выполняемыми с вашими объектами, и как только вы закончите свое действие, он выполняет соответствующие вызовы базы данных и отправляет запрос к базе данных.Этот паттерн является одним из центральных понятий, используемых NHibernate на, который использует объект, реализующий IDisposable, чтобы сигнализировать об окончании "работы".Это позволяет вам обернуть ваши действия в using и поручить подразделению работы обрабатывать действия за вас.

Редактировать:Дополнительная информация

Это это ссылка на базовую классовую структуру единицы работы ... на самом деле не самая захватывающая вещь в мире.Фаулер приводит более подробную информацию в своей книге, некоторые из которых вы можете увидеть здесь.Вы также можете посмотреть на объект Session из NHibernate как на возможную реализацию ( мне удалось отследить Изессия интерфейс ... не уверен, где находится реализация)

Надеюсь, это поможет.

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

Подход, который я использовал в прошлом, заключается в том, чтобы сделать тип контейнера достаточно умным для извлечения требуемых объектов.например:

public class Relation<T>
{
  private T _value;

  private void FetchData()
  {
    if( LoadData != null ) {
      LoadDataEventArgs args = new LoadDataEventArgs(typeof(T), /* magic to get correct object */);
      LoadData(this, args);
      _value = (T)args.Value;
    }
  }

  public event EventHandler<LoadDataEventArgs> LoadData;

  public T Value {
    get {
      if( _value == default(T) )
        FetchData();
      return _value; 
    }
    set { /* Do magic here. */ }
  }
}

Затем вы объявляете это в своей сущности следующим образом:

[RelationCriteria("ID", EqualsMyProperty="AddressID")]
public Relation<Address> Address {
  get; set;
}

И именно загрузчик типа, который объявляет свойство Address, должен добавить обработчик к событию loadData.

Аналогичный класс реализует IList, чтобы предоставить вам отношение "один ко многим".

На каком языке вы говорите?То, что вы описали, - это именно то, что Entity Framework делает в .Net.Но вы не сообщили, какой язык вы используете, и я предполагаю, что вы не хотите переписывать какой-либо из своих слоев данных.

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