#data-access-layer #business-logic
Вопрос:
(извините за мой английский) Например, в моем DAL у меня есть объект AuthorDB,у которого есть имя, и объект BookDB, у которого есть название и идентификатор автора.
Теперь, если я хочу показать все книги с соответствующим именем автора, я должен получить коллекцию всех книг и для каждой из них с атрибутом IdAuthor найти имя автора. Это создает множество запросов к базе данных, и, очевидно, можно использовать простое ОБЪЕДИНЕНИЕ.
Каковы мои варианты? Создание «пользовательского» объекта, содержащего имя автора и название книги? Если это так, то техническое обслуживание может стать ужасным.
Итак, какие есть варианты? Спасибо!
Ответ №1:
Не пишите что-то глючное, неэффективное и специализированное … когда доступны надежные, эффективные и универсальные инструменты. Бесплатно.
Выбери ОРМ. NHibernate, ActiveRecord, дозвуковой, NPersist, LinqToEF, LinqToSql, LLBLGenPro, DB4O, CSLA и др.
Ответ №2:
Вы можете создать представление в базе данных, в которое встроено соединение, и привязать к нему объект an, например AuthorBooksDB. Это не создает слишком большой головной боли при обслуживании, так как представление может скрывать любые основные изменения и остается статичным.
Ответ №3:
Если вы можете отделить запрос к базе данных от построения объекта, вы можете создать запрос для получения необходимых вам данных. Затем передайте эти данные своему разработчику, и пусть он вернет ваши книги.
С помощью Linq to SQL это можно сделать так же легко, как:
public IEnumerable<Book> AllBooks()
{
return from book in db.Books
join author in db.Authors on book.AuthorId equals author.Id
select new Book()
{
Title = book.Title,
Author = author.Name,
};
}
То же самое можно сделать с таблицами данных / наборами данных:
public IEnumerable<Book> AllBooks()
{
DataTable booksAndAuthors = QueryAllBooksAndAuthors(); // encapsulates the sql query
foreach (DataRow row in booksAndAuthors.Rows)
{
Book book = new Book();
book.Title = row["Title"];
book.Author = row["AuthorName"];
yield return book;
}
}
Ответ №4:
Большое вам спасибо за ваш вклад.
На самом деле мы стараемся, чтобы объекты базы данных были как можно ближе к фактическим столбцам соответствующей таблицы в базе данных. Вот почему мы действительно не можем добавить (строковый) атрибут «Автор» в объект BookDB.
Вот проблема, которую я вижу при использовании объектов «Просмотр». В базе данных, если схема должна быть изменена по какой-либо причине (например: В таблице книг столбец «Заголовок» должен быть изменен для «The_Title», как нам легко узнать все объекты «Представления», которые необходимо изменить? Другими словами, как мне узнать, какие объекты должны быть изменены, когда они выполняют запросы, использующие несколько соединений?
Здесь, поскольку у нас есть объект AuthorsBooks, мы можем видеть по имени, что он, вероятно, делает запрос к таблицам книг и авторов. Однако с объектами, которые выполняют 4 или 5 соединений между таблицами, мы не можем полагаться на имя объекта.
Есть какие-нибудь идеи? (Еще раз спасибо, это отличный сайт!)
Ответ №5:
Я предлагаю вам взглянуть на доменный дизайн. В DDD вы получаете все бизнес-объекты из репозитория. Хранилище скрывает ваше хранилище данных и реализацию, а также решит ваши проблемы с тем, как запрашивать данные и отслеживать изменения в базе данных. Поскольку каждый бизнес-объект извлекается из репозитория, репозиторий будет вашей единственной точкой изменения. Затем репозиторий может запросить вашу базу данных любым способом, который вы сочтете эффективным, а затем создать объекты домена на основе этих данных:
var books = new BookRepository().GetAllBooks();
Вы должны уметь кодировать репозитории с помощью любой из технологий, упомянутых Justice.