EF с POCO + WCF + WPF. Повторно использовать классы POCO на клиенте или использовать DTO? - PullRequest
3 голосов
/ 28 октября 2011

Мы разрабатываем 3-уровневое приложение с клиентом WPF, которое связывается через WCF с BLL.Мы используем EF для доступа к нашей базе данных.Мы использовали генератор кода EF по умолчанию для EntityObject, но у него было много проблем и проблем с сериализацией при отправке этих объектов по проводам, а также при обработке и повторном подключении их в BLL.шаблон POCO, и переписать доступ к данным и коммуникационные части нашего приложения (мы надеемся, что таким образом мы получим более чистую архитектуру и меньше «магического кода».

У меня вопрос: хорошая ли этоповторно использовать классы POCO на стороне клиента? Или мы должны создать отдельные классы DTO? Даже если они будут идентичны классам сущностей POCO? Каковы плюсы / минусы двух подходов?

Ответы [ 3 ]

3 голосов
/ 28 октября 2011

Обязательно используйте DTOs + AutoMapper.В противном случае у вас возникнет множество проблем с DataContractSerializer при использовании WCF из-за циклических зависимостей (особенно проблематичных с навигационными свойствами).Несмотря на то, что вы можете опустить DTO изначально, вы будете вынуждены использовать их позже из-за проблем, упомянутых выше.Поэтому я бы посоветовал использовать правильные DTO для каждого уровня.

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

2 голосов
/ 28 октября 2011

Сейчас я работаю над похожим вопросом. Я сделал следующее:

  1. Создать следующие сборки:

SF.Contracts - это только что определенные ServiceCotnracts и DataContracts. Очевидно, что все контракты данных могут использоваться как классы POCO в EF (но я не использую t4 или другой генератор - все классы POCO и DataContext написаны вручную, потому что мне нужно использовать очень плохую базу данных ). SF.

SF.DataAccessObjects - в этой сборке я реализую мои edmx и DataContext. SF.Services - внедрение служб WCF.

Итак, большое количество методов выбора WCF имеют следующую подпись и реализацию:

        public List<Vulner> VulnerSelect(int[] idList = null, string[] navigationPropertiesList = null)
    {
        var query = from vulner in _businessModel.DataModel.VulnerSet
                    select vulner;

        if (navigationPropertiesList != null)
            navigationPropertiesList.Select(p =>{query = ((ObjectQuery<Vulner>)query).Include(p);
                                   return true; });
        if (idList != null)
            query = query.Where(p => idList.Contains(p.Id));

        return query.ToList();
    }

и вы можете использовать этот метод следующим образом:

WCFproxy.VulnerSelect(new[]{1,2,3},new[]{"SecurityObjects", "SecurityObjrcts.Problem"});

чтобы у вас не было проблем с сериализацией, свойствами навигации и т. Д., И вы могли четко указать, какие свойства NavigationProperties должны быть загружены.

p.s .: извините за мой плохой английский:)

1 голос
/ 28 октября 2011

Я бы сказал, использовать DTO.

Круговые зависимости и большие графы объектов могут быть серьезной проблемой, вызывающей либо ошибки, либо слишком много сериализованного трафика. Просто слишком много шума на управляемом объекте ORM, чтобы отправить его по линии.

Я использую сервисный уровень для доступа к своим доменным объектам и широко использую LINQ, но я всегда возвращаю объекты DTO обратно клиенту.

...