2009-09-02 2 views
1

Я читаю книгу «ASP.NET 3.5 Social Networking - Andrew Siemer», и я смутился, когда он использовал репозитории для доступа к данным.Репозиторий данных - бизнес-объекты?

Вот идея его кода:

public interface IAccountRepository 
{ 
    Account GetAcountByID(int acId); 
    void SaveAccount(Account account); 
    List<Account> GetAllAccounts();  
} 

public class AccountRepositoryLINQ : IAccountRepository 
{ 
    Account GetAcountByID(int acId){ 
    ..... LINQ query ..... 
    ...... return..... 
    } 
    void SaveAccount(Account account){ 
    ..... LINQ ..... 
    } 
    List<Account> GetAllAccounts(){ 
    ..... LINQ query ..... 
    ...... return..... 
    } 
} 

Класс «Счет» является один генерируется автоматически на «LINQ к классам SQL».

Некоторые из проблем, которые я вижу:

Я закодировать свой бизнес слой, GUI, и т.д. ... и позже во время, табличные счета в базе данных изменяются (пример: изменить имя одного столбца), тогда мне нужно перестроить «LINQ to SQL Classes», и все мои слои кода должны быть перекодированы, потому что изменился мой объект «Account».

Если мне нужно иметь другие репозитории (MySQL, Oracle, XML, другие), какой класс "Счет" будет использовать?

Что делать?

  • Не следует использовать специальный класс учетной записи? Это будет использоваться во всех слоях приложения.
  • Как сопоставление LINQ с моим пользовательским классом учетной записи?
    • Использование простого «myClass.Name = linqClass.Name;» ???
      • Разве это не ресурсы потребляющих машин, если мне нужно «отобразить» все классы?
      • Существует не самый простой/легкий способ сделать это?
      • Правильно ли это? Есть ли другие способы?

ответ

1

У меня есть отношения любви ненависти с помощью LINQ к классам SQL сам, но я думал, что я буду играть черти выступать :-), во-первых, обращаясь очков вы сделали: -

1º Я закодировать свой бизнес слой , GUI, и т. Д. ... и позже в таблице Учетные записи в базе данных изменены (пример: измените имя одного столбца ), тогда мне нужно перестроить «LINQ to SQL Classes» и все мои код слоев необходимо будет перекодировать, потому что изменен объект «Учетная запись».

Общий подход заключается в том, что вы добавили бы поведение к частичным классам, сгенерированным LINQ to SQL, эти файлы не будут заменены при обновлении таблицы из контекста данных. Если вы измените имя столбца и не хотите изменять остальную часть кода, просто обновите класс в конструкторе, чтобы использовать имя старого столбца?

Даже если вы использовали POCOs для настойчивости с NHibernate, например, вам все равно нужно изменить отображение, поэтому я действительно не вижу в этом проблемы.

2º Если мне нужно иметь другие репозитории (MySQL, Oracle, XML, другие), какой класс "Счет" будет использовать?

Лично я бы назвал YAGNI на этом, если вы действительно ожидаете, нуждаются в поддержке для нескольких баз данных LINQ к SQL не может быть лучшим решения для начала в любом случае (просто сохранить инфраструктуру последовательно через приложение), такие инструменты, как NHibernate, имели бы гораздо лучшую поддержку для таких ситуаций.

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

В конце концов, это может быть вполне правдоподобно, чтобы иметь полный контроль над вашими сущностями (например, не нужно использовать конструктор без параметров, контроль над установкой и т. Д., Простые типы пользователей, которые сопоставляются с одним или двумя столбцами), и если вы чувствуете, что ваше приложение может извлечь выгоду из этого, это, вероятно, путь, но вы заплатите цену за реализацию репозитория, которая будет сложна при сопоставлении кода и обработке того, нужно ли обновлять/удалять/вставлять вещи.

Хорошим средним уровнем может быть просто код интерфейса (например, IAccount), это должно определять свойства и метод, которые вы ожидаете от учетной записи. Ваше хранилище будет затем стать

IAccount GetById(int accountId); 

Вы тогда дать себе свободу над тем, что его реализация (т.е. является ли это реализовано с помощью LINQ к классу SQL или проекции/отображения), и если вы выберете для пользовательского класса в будущем это будет простой случай перехода реализации к этому классу и изменения реализации репозитория.

В конце концов, дело доходит до приложения, если вы считаете, что это приведет к огромному приложению с чрезвычайно сложной бизнес-логикой, я бы выбрал изолированный доменный уровень, который, по крайней мере, пытается быть ненасытным. Если, однако, это не так, и выбор шаблона репозитория - это просто средство для достижения хорошей тестируемости и простой абстракции над доступом к данным. Я не понимаю, почему явное обращение к классам LINQ to SQL и использование их в качестве простого уровня домена является таким большим делом.

2

Хороший инстинкт ..

Мое предложение, чтобы абстрагироваться от объектов LinqToSql и создать набор объектов предметной области бизнеса. Затем репозиторий может запросить необходимые данные и сопоставить их с объектами Domain, которые использует ваше приложение, и вернуть их. Теперь ваш уровень доступа к данным отделен от вашего приложения, и теперь вы можете выполнять все перечисленные вами вещи.

Отображение может быть больно, поэтому посмотрите на такие инструменты, как Automapper, чтобы выполнить это.

0

Я лично использую сочетание NHibernate и FluentNHibernate и разделяю свой домен (бизнес-объекты) со всеми остальными. Я использую сообщения из моих других слоев, например GUI, в свой домен, у которого есть обработчик, который внедряет репозитории внутри, которые увлажняют рассматриваемый объект (ы) и выполняют бизнес-логику, интерфейсы в вышеперечисленных хранилищах - отличный способ отделить если вы хотите использовать другие реализации репозиториев или доступа к данным.

Смежные вопросы