Где объекты объединяются/соединяют данные в 3-уровневой модели?
-
24-10-2019 - |
Вопрос
Это вероятность простой 3-уровневой проблемы. Я просто хочу убедиться, что мы используем лучшую практику для этого, и я еще не так семейный со структурами.
У нас есть 3 уровня:
- GUI: ASP.NET для презентации Layer (первая платформа)
- BAL: Business-Layer будет обрабатывать логику на веб-сервере в C#, поэтому мы оба можем использовать ее для WebForms/MVC + Webservices
- DAL: LINQ TO SQL в Layer Data, возвращая BusinessObjects, а не LINQ.
- DB: SQL будет Microsoft SQL-Server/Express (еще не решил).
Давайте подумаем о настройке, где у нас есть база данных [лиц]. Все они могут иметь несколько [адреса], и у нас есть полный список всех [почтового кода], соответствующих городских и т. Д. И т. Д.
Сделка в том, что мы присоединились к многочисленным деталям из других таблиц.
{Отношения}/[таблицы
- Человек]: 1 --- n: {PersonAddress}: M --- 1: [Адрес
- Адрес]: n --- 1: [почтовый индекс
Теперь мы хотим построить DAL для человека. Как должен выглядеть персонбо и когда происходит соединения? Является ли это проблемой для бизнеса для получения всех CityNames и возможных адресов PR. Человек? Или DAL должен завершить все это, прежде чем вернуть персону в BAL?
Class PersonBO
{
public int ID {get;set;}
public string Name {get;set;}
public List<AddressBO> {get;set;} // Question #1
}
// Q1: Извлекаем ли мы объекты перед возвращением Персона, и вместо этого это будет массив? Или это совершенно неправильно для N-уровня/3-уровневого ??
Class AddressBO
{
public int ID {get;set;}
public string StreetName {get;set;}
public int PostalCode {get;set;} // Question #2
}
// Q2: мы делаем поиск или просто оставляем почтовый код для дальнейшего поиска?
Кто -нибудь может объяснить в каком порядке, чтобы вытащить какие объекты? Конструктивная критика очень приветствуется. : o)
Решение
Вы как бы переосмысливаете колесо; Ормс уже решает большую часть этой проблемы для вас, и вам будет немного сложно сделать себя.
То, как Ормы, такие как LINQ, SQL, Ontity Framework и Nhibernate Do Это метод, называемый ленивая загрузка ассоциаций (которые могут быть при желании быть переопределены с нетерпеливой нагрузкой).
Когда вы подтягиваете Person
, это не загружает Address
Пока вы специально не спросите об этом, в этот момент происходит другая поездка на базу данных (ленивая нагрузка). Вы также можете указать на основе для каждого, что вам нужно Address
быть загруженным для каждый человек (нетерпеливая нагрузка).
В некотором смысле, с этим вопросом вы в основном спрашиваете, должны ли вы выполнять ленивые или нетерпеливые нагрузки AddressBO
для PersonBO
, и ответ: ни один. Нет единого подхода, который универсально работает. По умолчанию Вы, вероятно, должны лениться, чтобы не делать много ненужных соединений; Чтобы справиться с этим, вам придется построить свой PersonBO
с механизмом ленивого загрузки, который поддерживает некоторую ссылку на DAL. Но вы по-прежнему захотите иметь возможность для нетерпеливой загрузки, которую вам понадобится встроить в свою логику «доступа к бизнесу».
Другой вариант, если вам необходимо вернуть высокопоставленный набор данных с определенными свойствами, заполненными множеством различных таблиц,-это не возвращать PersonBO
вообще, но вместо этого используйте Объект передачи данных (DTO). Если вы реализуете механизм ленивого загрузки по умолчанию, вы можете иногда заменить это как нетерпеливую версию.
К вашему сведению, ленивые погрузчики в структуре доступа к данным обычно строятся с логикой загрузки в самой ассоциации:
public class PersonBO
{
public int ID { get; set; }
public string Name { get; set; }
public IList<AddressBO> Addresses { get; set; }
}
Это просто Поко, волшебство происходит в реальной реализации списка:
// NOT A PRODUCTION-READY IMPLEMENTATION - DO NOT USE
internal class LazyLoadList<T> : IList<T>
{
private IQueryable<T> query;
private List<T> items;
public LazyLoadList(IQueryable<T> query)
{
if (query == null)
throw new ArgumentNullException("query");
this.query = query;
}
private void Materialize()
{
if (items == null)
items = query.ToList();
}
public void Add(T item)
{
Materialize();
items.Add(item);
}
// Etc.
}
(Это, очевидно, не производительность, это просто для того, чтобы продемонстрировать технику; вы начинаете с запроса и не материализуете фактический список, пока не придется.)