Где объекты объединяются/соединяют данные в 3-уровневой модели?

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

Вопрос

Это вероятность простой 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.
}

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

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