Путаница между DTO (linq2sql) и объектами Class! - PullRequest
6 голосов
/ 24 августа 2009

я успешно работал с linq2sql и linq DTO (классы, созданные linq2sql) ....

Я запутался, у меня есть задача обновить старое приложение, и я вижу, что мои DTO будут использоваться так, как они должны быть .... для переноса даты

Я использую шаблон репозитория, поэтому я передаю данные из репозитория в сервис через linq2sql dtos ... как только я попадаю на уровень сервиса (это в основном моя бизнес-логика), тогда мне нужно обойти объекты класса ..

эти объекты класса в основном являются зеркальным отображением (более или менее) dtos - в некоторых местах есть некоторые изменения, но, как правило, то же самое.

Итак, вернемся к вопросу в руках! - это хорошая практика, чтобы использовать dtos только для передачи данных из хранилища на уровень обслуживания ... и однажды на уровне обслуживания (бизнес-логика) я должен, но отображать все мои dtos на части счетчика объектов класса (конечно, с помощью automapper! !)

Моя другая альтернатива - продолжать использовать DTOS, подобные объектам классов, и передавать их из метода в метод, а также в качестве возвращаемых типов и т. Д., Но я чувствую, что это плохая практика, и я продолжаю ходить по кругу, задаваясь вопросом, какой метод мне следует применять?

Любая помощь действительно ценится

спасибо

Ответы [ 4 ]

5 голосов
/ 24 августа 2009

Вот мое мнение: При работе с любым нетривиальным приложением. Использование ваших объектов linq2Sql в качестве модели вашего домена - очень плохая идея. Я вижу linq2Sql как ORM и ничего более. Базы данных (которым linq2Sql имеет прямое соответствие) - это нормализация data . Классы (в смысле OOAD) являются нормализацией поведения (не данных).

[эти объекты класса являются зеркальным отражением] ...

Я сталкивался с этим при создании приложений с помощью linq2Sql. Давайте будем реалистами ... большинство бизнес-приложений - это прославленные CRUD-приложения. Поэтому не исключено, что большой процент объектов вашего приложения будет напрямую соответствовать таблицам базы данных. Я не хотел связываться напрямую с генерируемыми DTO, но в то же время я не хотел, чтобы дубликаты классов были засорены в моем приложении.

Так вот мое решение:
Я "запрограммирован на интерфейс".

Допустим, у меня есть PersonDto (Dto означает объект передачи данных) со свойствами FirstName, LastName, Age (которые имеют непосредственное отношение к столбцам базы данных).

Я создал IPerson интерфейс, и мой PersonD реализовал его.


  [Table(Name="Persons")]
  internal class PersonDto : IPerson
  {
      ....
  }

И мой метод репозитория будет принимать и извлекать IPerson в отличие от класса Linq2Sql.


    IPerson somePerson = _repository.Get(someGuid);
    somePerson.FirstName = "SomeName";
    _repository.Save(somePerson);

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

Некоторые общие указатели: Создайте свой DTO вручную ... Я знаю, это звучит безумно, но вы обнаружите, что он действительно хорошо работает с подходом к разработке сверху вниз. Ваши объекты DTO (linq2Sql) будут чрезвычайно легкими и будут открыты для изменений за пределами конструктора .dbml.

Храните ваши DTO и DataContext внутри. Нет причин для публичного представления ваших dto (учитывая, что у вас есть открытые интерфейсы для ваших репозиториев и доменных объектов). Это приведет к логическому разделению между моделью вашего домена и доступом к данным.

Поместите все уровни доступа к данным в отдельный проект (снова, чтобы обеспечить это разделение).

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

Надеюсь, это поможет ...

3 голосов
/ 24 августа 2009

У меня действительно был похожий вопрос по этой теме, хотя мои намерения были немного другими. Рекомендовалось использовать классы Linq2SQL в качестве объектов домена и использовать преимущества частичных классов, как уже упоминали другие. Мое главное беспокойство касалось формы этих объектов (например, имен свойств) и доступности членов класса (например, private v.s. protected).

Форма объектов и даже доступность могут быть решены с помощью шаблонов t4, где Damien Guard собрал шаблон T4, чтобы вы могли контролировать форму классов, которые Linq2Sql будет генерировать для вас. Это можно увидеть здесь Шаблон T4 для Linq2SQL .

Это подход, который я собираюсь рассмотреть и решить, отвечает ли он моим проблемам. Кроме того, если ваш сервисный уровень может принимать интерфейсы с аргументами методов, вы также можете контролировать доступ к сервисному уровню через обертки интерфейса вокруг ваших DTO Linq2SQL.

Надеюсь, это поможет.

2 голосов
/ 24 августа 2009

Это одно из лучших обсуждений темы, которую я видел:

http://blog.wekeroad.com/blog/linqtosql-momma-said-knock-you-out/

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

Когда ваше приложение перерастет LinqToSql, насколько легко будет вытащить LinqToSql и вставить на его место другой ORM? Это то, что вы должны серьезно подумать.

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

0 голосов
/ 24 августа 2009

Классы, сгенерированные конструктором linq2sql, являются частичными классами, поэтому вы можете расширить их и поместить в них свою бизнес-логику. Идея состоит в том, что linq используется для сохранения / восстановления этих объектов, чтобы вы могли избежать того типа отображения, о котором вы говорите.

...