WCF, Entity Framework & Data Contracts - PullRequest
7 голосов
/ 14 июля 2009

Использование VS 2008 и .NET 3.5 SP1:

Я использую WCF, чтобы позволить клиентам подключаться к службе, которая читает и записывает записи базы данных с использованием Entity Framework. По умолчанию к объектам, которые автоматически создаются из базы данных, применяется атрибут DataContract.

К сожалению, многие из этих полей не предназначены для использования клиентом (т. Е. Записи о том, кто какие данные получает доступ и т. Д.), И из соображений безопасности я бы предпочел не раскрывать их. Есть ли способ избежать выставления классов Entity Framework таким способом?

Примечание : Это не дубликат Как предотвратить раскрытие частных свойств в объектах .NET как общедоступных через службы? . В этом вопросе пользователь хочет выборочно отображать определенные поля, тогда как я хотел бы, чтобы сущность вообще не отображалась как DataContract.

Заранее спасибо.

Ответы [ 3 ]

13 голосов
/ 14 июля 2009

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

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

С другой стороны, я всегда рекомендую не выставлять объекты Entity Framework через веб-сервис. К сожалению, Microsoft предоставляет свойства, зависящие от реализации, помечая их как [DataMember]. Я только что попробовал это с помощью простого сервиса, возвращающего SalesOrderHeader из AdventureWorks. Мой клиент получил прокси-версии следующих типов EF:

  • EntityKeyMember
  • StructuralObject
  • EntityObject
  • EntityKey
  • EntityReference
  • RelatedEnd

Это не то, о чем ваши клиенты должны знать.

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

Опция, которую я не пробовал: AutoMapper .

3 голосов
/ 14 июля 2009

Мы используем отдельные классы для объектов DataContract. У нас есть интерфейс с одним методом ToContract (), и все наши объекты реализуют этот интерфейс в файле частичного класса. Это дополнительная работа, и это шаблон, но кажется, что это самый простой способ получить необходимое разделение и детальность контроля.

2 голосов
/ 14 июля 2009

Я в основном вижу две вещи, которые вы можете сделать:

  1. Либо вы удаляете те элементы, которые вы не хотите открывать, из DataContract, вручную удаляя атрибут [DataMember] для этих элементов; в этом случае WCF не будет сериализовать свойства
  2. Вы определяете свои собственные классы WCF DataContract только с теми членами, которые вам нужны, и вы придумываете логику для преобразования из ваших EF-сущностей в ваш WCF DataContract, используя, например, что-то вроде AutoMapper для устранения (или, по крайней мере, ограничения) утомительных операций присвоения между сущностями EF и WCF.

Марк

...