Каковы лучшие практики при создании слоя доступа к данным для объекта, который имеет ссылку на другой объект? - PullRequest
0 голосов
/ 11 октября 2008

(извините за мой английский) Например, в моем DAL у меня есть объект AuthorDB, который имеет имя и объект BookDB с заголовком и идентификатором IdAuthor.

Теперь, если я хочу показать все книги с соответствующим именем автора, я должен получить коллекцию всех книг и для каждой из них с атрибутом IdAuthor найти имя автора. Это делает много запросов к базе данных, и, очевидно, можно использовать простой JOIN.

Какие у меня варианты? Создание «пользовательского» объекта, который содержит имя автора и название книги? Если это так, обслуживание может стать ужасным.

Итак, какие есть варианты? Спасибо!

Ответы [ 5 ]

3 голосов
/ 12 октября 2008

Не пишите что-то глючное, неэффективное и специализированное ... когда доступны надежные, эффективные и универсальные инструменты. Бесплатно.

Выберите ОРМ. NHibernate, ActiveRecord, SubSonic, NPersist, LinqToEF, LinqToSQL, LLBLGenPro, DB4O, CSLA и др.

0 голосов
/ 13 октября 2008

Предлагаю вам взглянуть на Domain Driven Design. В DDD вы получаете все бизнес-объекты из хранилища. Репозиторий скрывает ваше хранилище данных и реализацию и решит ваши проблемы с тем, как запрашивать данные и отслеживать изменения базы данных. Поскольку каждый бизнес-объект извлекается из хранилища, хранилище станет вашей единственной точкой изменений. Затем репозиторий может запросить вашу базу данных любым способом, который сочтет вам эффективным, а затем построить объекты домена из этих данных:

var books = new BookRepository().GetAllBooks();

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

0 голосов
/ 12 октября 2008

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

С помощью 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,
                        };
}

Того же можно добиться с помощью DataTables / DataSets:

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;
    }
}
0 голосов
/ 12 октября 2008

Большое спасибо за ваш вклад.

На самом деле мы стараемся максимально приблизить объекты базы данных к фактическим столбцам соответствующей таблицы в базе данных. Вот почему мы не можем действительно добавить (строковый) атрибут Author к объекту BookDB.

Вот проблема, которую я вижу при использовании объектов «Просмотр». В базе данных, если схема должна быть изменена по какой-либо причине (например, в таблице «Книга» столбец «Заголовок» необходимо изменить для «The_Title»), как мы легко узнаем все объекты «Вид», быть измененным? Другими словами, как узнать, какие объекты нужно изменить, когда они выполняют запросы, использующие множественные объединения?

Здесь, поскольку у нас есть объект AuthorsBooks, мы видим по имени, что он, вероятно, выполняет запрос к таблицам book и author. Однако с объектами, которые выполняют 4 или 5 объединений между таблицами, мы не можем полагаться на имя объекта.

Есть идеи? (Еще раз спасибо, это отличный сайт!)

0 голосов
/ 11 октября 2008

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

...