Обработка рассчитанных свойств с помощью breezejs и web api

Я экспериментирую с BreezeJS с веб-API, используя BreezeControllerAttribute. Как должны отображаться рассчитанные свойства объекта? Единственный способ, которым я нашел это, – создать промежуточный DTO, который наследуется от сущности или использует проекцию. Обычно для этого сценария я бы использовал свойство readonly, но они, похоже, игнорируются.

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

К счастью, вы можете научить Breeze распознавать свойство, зарегистрировав его как неотображенное свойство . Я покажу вам, как это сделать. Позвольте мне сначала рассказать.

Задний план

Ваше вычисленное свойство будет «известным» клиенту Breeze, если бы оно было рассчитано базой данных. Свойства базы данных (регулярные и рассчитанные) подбираются в метаданных как отображаемые свойства.

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

Я предполагаю, что вы не скрываете его от сериализатора. Если вы посмотрите на сетевой трафик для запроса classа, вы можете увидеть полученные вами данные о свойствах, поступающие на клиент. Проблема в том, что Breeze игнорирует его, когда он «материализует» сущности из этих результатов запроса.

Решение с примером

Решение заключается в регистрации вычисленного свойства в MetadataStore .

Я изменил sampleExtensionTests.js образца DocCode, чтобы включить этот сценарий; вы можете получить этот код от GitHub или дождаться следующего выпуска Breeze.

Или просто следуйте приведенному ниже коду, начиная с этого fragmentа из classа Employee в NorthwindModel.cs :

 // Unmapped, вычисленное свойство на стороне сервера
 [NotMapped] // Скрыт от Entity Framework;  все еще сериализован для клиента
 public string FullName { 
     get {return LastName + 
              (String.IsNullOrWhiteSpace (FirstName)? "": ("," + FirstName));  }
 }

И вот автоматический тест в entityExtensionTests.js

 test («unmapped property может быть задано вычисленным свойством classа сервера», 2,
   function () {

     var store = cloneModuleMetadataStore ();  // клонирует метаданные Northwind

     // пользовательский конструктор Employee
     var employeeCtor = function () {
         // 'Fullname' - это вычисленное свойство на стороне сервера classа Employee
         // Это свойство unmapped будет пустым для новых объектов
         // но будет установлен для существующих объектов во время материализации запроса
         this.FullName = ""; 
     };

     // регистрируем пользовательский конструктор
     store.registerEntityTypeCtor («Сотрудник», employeeCtor);

     var fullProp = store.getEntityType ('Employee'). getProperty ('FullName');
     ok (fullProp && fullProp.isUnmapped,
         «FullName» должно быть без изменений после регистрации »);

     var em = newEm (store);  // helper создает менеджера, используя этот MetadataStore

     var query = EntityQuery.from («Сотрудники») с использованием (em);

     стоп();  // идущий async
     . Query.execute (), а затем (успех) .fail (handleFail) .fin (старт);

     успех функции (данные) {
         var first = data.results [0];
         var full = first.FullName ();

         // проходящий тест подтверждает, что свойство FulllName имеет значение
         ok (full, «queried« Employee »должен иметь полное имя (« Last, First »),« + full »;
     }

 });

Что вам нужно сделать, это небольшая часть тестового примера:

 var yourTypeCtor = function () {
     this.calculatedProperty = "";  // "" или экземпляр любого типа должен быть
 };

 // регистрируем свой пользовательский конструктор
 store.registerEntityTypeCtor ("YourType", yourTypeCtor);
Давайте будем гением компьютера.