diff --git a/NewPlatform.Flexberry.ORM.ODataService/Controllers/DataObjectController.ModifyData.cs b/NewPlatform.Flexberry.ORM.ODataService/Controllers/DataObjectController.ModifyData.cs
index 074b815d..9a7c0ab8 100644
--- a/NewPlatform.Flexberry.ORM.ODataService/Controllers/DataObjectController.ModifyData.cs
+++ b/NewPlatform.Flexberry.ORM.ODataService/Controllers/DataObjectController.ModifyData.cs
@@ -635,7 +635,7 @@ private DataObject UpdateObject(EdmEntityObject edmEntity, object key)
{
// Создадим объект данных по пришедшей сущности.
// В переменной objs сформируем список всех объектов для обновления в нужном порядке: сам объект и зависимые всех уровней.
- DataObject obj = GetDataObjectByEdmEntity(edmEntity, key, objs);
+ DataObject obj = GetDataObjectByEdmEntity(edmEntity, key, objs, useUpdateView: true);
for (int i = 0; i < objs.Count; i++)
{
@@ -698,12 +698,13 @@ private DataObject UpdateObject(EdmEntityObject edmEntity, object key)
}
///
- /// Получить объект данных по ключу: если объект есть в хранилище, то возвращается загруженным по представлению по умолчанию, иначе - создаётся новый.
+ /// Получить объект данных по ключу: если объект есть в хранилище, то возвращается загруженным по представлению , иначе - создаётся новый.
///
/// Тип объекта, не может быть null.
- /// Значение ключа.>
+ /// Значение ключа.
+ /// Представление для загрузки объекта.
/// Объект данных.
- private DataObject ReturnDataObject(Type objType, object keyValue)
+ private DataObject ReturnDataObject(Type objType, object keyValue, View view)
{
if (objType == null)
{
@@ -713,7 +714,6 @@ private DataObject ReturnDataObject(Type objType, object keyValue)
if (keyValue != null)
{
DataObject dataObjectFromCache = DataObjectCache.GetLivingDataObject(objType, keyValue);
- View view = _model.GetDataObjectDefaultView(objType);
if (dataObjectFromCache != null)
{
@@ -727,16 +727,7 @@ private DataObject ReturnDataObject(Type objType, object keyValue)
IEnumerable ownProps = view.Properties.Where(p => !p.Name.Contains('.'));
if (!ownProps.All(p => loadedProps.Contains(p.Name)))
{
- // Вычитывать объект сразу с детейлами нельзя, поскольку в этой же транзакции могут уже оказать отдельные операции с детейлами и перевычитка затрёт эти изменения.
- View miniView = view.Clone();
- DetailInView[] miniViewDetails = miniView.Details;
- miniView.Details = new DetailInView[0];
- _dataService.LoadObject(miniView, dataObjectFromCache, false, true, DataObjectCache);
-
- if (miniViewDetails.Length > 0)
- {
- _dataService.SafeLoadDetails(view, new DataObject[] { dataObjectFromCache }, DataObjectCache);
- }
+ _dataService.SafeLoadObject(dataObjectFromCache, view, DataObjectCache);
}
}
@@ -782,6 +773,28 @@ private DataObject ReturnDataObject(Type objType, object keyValue)
return obj;
}
+ ///
+ /// Добавляет объект данных в список на обновление если его там ещё нет.
+ ///
+ /// Список на обновление.
+ /// Объект данных который добавляем.
+ /// Добавлять в конец списка.
+ private static void AddDataObject(List objsToUpdate, DataObject dataObject, bool insertToEnd)
+ {
+ bool objAlreadyExists = objsToUpdate.Any(o => PKHelper.EQDataObject(o, dataObject, false));
+ if (!objAlreadyExists)
+ {
+ if (insertToEnd)
+ {
+ objsToUpdate.Add(dataObject); // Добавляем в конец списка.
+ } else
+ {
+ objsToUpdate.Insert(0, dataObject); // Добавляем объект в начало списка.
+ }
+
+ }
+ }
+
///
/// Построение объекта данных по сущности OData.
///
@@ -789,21 +802,20 @@ private DataObject ReturnDataObject(Type objType, object keyValue)
/// Значение ключевого поля сущности.
/// Список объектов для обновления.
/// Признак, что объект добавляется в конец списка обновления.
+ /// Использовать представление для обновления (вместо представления по умолчанию).
/// Объект данных.
- private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object key, List dObjs, bool endObject = false)
+ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object key, List dObjs, bool endObject = false, bool useUpdateView = false)
{
if (edmEntity == null)
{
return null;
}
- IEdmEntityType entityType = (IEdmEntityType)edmEntity.ActualEdmType;
- Type objType = _model.GetDataObjectType(_model.GetEdmEntitySet(entityType).Name);
-
// Значение свойства.
object value;
// Получим значение ключа.
+ IEdmEntityType entityType = (IEdmEntityType)edmEntity.ActualEdmType;
IEnumerable entityProps = entityType.Properties().ToList();
var keyProperty = entityProps.FirstOrDefault(prop => prop.Name == _model.KeyPropertyName);
if (key != null)
@@ -815,26 +827,21 @@ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object ke
edmEntity.TryGetPropertyValue(keyProperty.Name, out value);
}
- // Загрузим объект из хранилища, если он там есть (используем представление по умолчанию), или создадим, если нет, но только для POST.
+ // Загрузим объект из хранилища, если он там есть, или создадим, если нет, но только для POST.
// Тем самым гарантируем загруженность свойств при необходимости обновления и установку нужного статуса.
- DataObject obj = ReturnDataObject(objType, value);
+ Type objType = _model.GetDataObjectType(edmEntity);
- // Добавляем объект в список для обновления, если там ещё нет объекта с таким ключом.
- var objInList = dObjs.FirstOrDefault(o => PKHelper.EQDataObject(o, obj, false));
- if (objInList == null)
+ View view = _model.GetDataObjectDefaultView(objType);
+ if (useUpdateView)
{
- if (!endObject)
- {
- // Добавляем объект в начало списка.
- dObjs.Insert(0, obj);
- }
- else
- {
- // Добавляем в конец списка.
- dObjs.Add(obj);
- }
+ view = _model.GetDataObjectUpdateView(objType) ?? view;
}
+ DataObject obj = ReturnDataObject(objType, value, view);
+
+ // Добавляем объект в список для обновления, если там ещё нет объекта с таким ключом.
+ AddDataObject(dObjs, obj, endObject);
+
// Все свойства объекта данных означим из пришедшей сущности, если они были там установлены(изменены).
string agregatorPropertyName = Information.GetAgregatePropertyName(objType);
IEnumerable changedPropNames = edmEntity.GetChangedPropertyNames();
@@ -876,7 +883,7 @@ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object ke
{
// Порядок вставки влияет на порядок отправки объектов в UpdateObjects это в свою очередь влияет на то, как срабатывают бизнес-серверы. Бизнес-сервер мастера должен сработать после, а агрегатора перед этим объектом.
bool insertIntoEnd = string.IsNullOrEmpty(agregatorPropertyName);
- DataObject master = GetDataObjectByEdmEntity(edmMaster, null, dObjs, insertIntoEnd);
+ DataObject master = GetDataObjectByEdmEntity(edmMaster, null, dObjs, insertIntoEnd, useUpdateView);
Information.SetPropValueByName(obj, dataObjectPropName, master);
@@ -913,7 +920,8 @@ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object ke
(EdmEntityObject)edmEnt,
null,
dObjs,
- true);
+ true,
+ useUpdateView);
if (det.__PrimaryKey == null)
{
@@ -1008,20 +1016,7 @@ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object ke
if (agregator != null)
{
- DataObject existObject = dObjs.FirstOrDefault(o => PKHelper.EQDataObject(o, agregator, false));
- if (existObject == null)
- {
- if (!endObject)
- {
- // Добавляем объект в начало списка.
- dObjs.Insert(0, agregator);
- }
- else
- {
- // Добавляем в конец списка.
- dObjs.Add(agregator);
- }
- }
+ AddDataObject(dObjs, agregator, endObject);
}
}
diff --git a/NewPlatform.Flexberry.ORM.ODataService/Extensions/DataServiceExtensions.cs b/NewPlatform.Flexberry.ORM.ODataService/Extensions/DataServiceExtensions.cs
index 9d0ddd9b..e7630b3b 100644
--- a/NewPlatform.Flexberry.ORM.ODataService/Extensions/DataServiceExtensions.cs
+++ b/NewPlatform.Flexberry.ORM.ODataService/Extensions/DataServiceExtensions.cs
@@ -179,6 +179,37 @@ public static void SafeLoadDetails(this IDataService dataService, View view, ILi
}
}
+ ///
+ /// Догрузка объекта по указанному представлению, с загрузкой детейлов с сохранением состояния изменения.
+ ///
+ /// Экземпляр сервиса данных.
+ /// Объект данных, который нужно догрузить.
+ /// Представление, которое используется для догрузки.
+ /// Кеш объектов данных.
+ public static void SafeLoadObject(this IDataService dataService, DataObject dataObject, View view, DataObjectCache dataObjectCache)
+ {
+ if (dataService == null)
+ {
+ throw new ArgumentNullException(nameof(dataService));
+ }
+
+ if (view == null)
+ {
+ throw new ArgumentNullException(nameof(view));
+ }
+
+ // Вычитывать объект сразу с детейлами нельзя, поскольку в этой же транзакции могут уже оказать отдельные операции с детейлами и перевычитка затрёт эти изменения.
+ View miniView = view.Clone();
+ DetailInView[] miniViewDetails = miniView.Details;
+ miniView.Details = new DetailInView[0];
+ dataService.LoadObject(miniView, dataObject, false, true, dataObjectCache);
+
+ if (miniViewDetails.Length > 0)
+ {
+ dataService.SafeLoadDetails(view, new DataObject[] { dataObject }, dataObjectCache);
+ }
+ }
+
///
/// Add detail object to agregator according detail type.
///
diff --git a/NewPlatform.Flexberry.ORM.ODataService/Model/DataObjectEdmModel.cs b/NewPlatform.Flexberry.ORM.ODataService/Model/DataObjectEdmModel.cs
index c386f791..dcfae14f 100644
--- a/NewPlatform.Flexberry.ORM.ODataService/Model/DataObjectEdmModel.cs
+++ b/NewPlatform.Flexberry.ORM.ODataService/Model/DataObjectEdmModel.cs
@@ -511,6 +511,21 @@ public View GetDataObjectDefaultView(Type dataObjectType)
}
return _metadata[dataObjectType].DefaultView.Clone();
+ }
+
+ ///
+ /// Осуществляет получение представления для обновления объекта, соответствующего заданному типу объекта данных.
+ ///
+ /// Тип объекта данных, для которого требуется получить представление для обновления.
+ /// Представление для обновления объекта, соответствующее заданному типу объекта данных.
+ public View GetDataObjectUpdateView(Type dataObjectType)
+ {
+ if (dataObjectType == null)
+ {
+ throw new ArgumentNullException(nameof(dataObjectType), "Contract assertion not met: dataObjectType != null");
+ }
+
+ return _metadata[dataObjectType].UpdateView?.Clone();
}
///
@@ -534,7 +549,7 @@ public List GetTypes(List strTypes)
///
/// Осуществляет получение типа объекта данных, соответствующего заданному имени набора сущностей в EDM-модели.
///
- /// Имя набора сущностей в EDM-модели, для которого требуется получить представление по умолчанию.
+ /// Имя набора сущностей в EDM-модели, для которого требуется получить тип.
/// Типа объекта данных, соответствующий заданному имени набора сущностей в EDM-модели.
public Type GetDataObjectType(string edmEntitySetName)
{
@@ -554,6 +569,22 @@ public Type GetDataObjectType(string edmEntitySetName)
return dataObjectType;
}
+ ///
+ /// Осуществляет получение типа объекта данных, соответствующего заданной сущности в EDM-модели.
+ ///
+ /// Сущность в EDM-модели, для которой требуется получить тип.
+ /// Типа объекта данных, соответствующий заданной сущности в EDM-модели.
+ public Type GetDataObjectType(EdmEntityObject edmEntity)
+ {
+ if (edmEntity == null)
+ {
+ throw new ArgumentNullException(nameof(edmEntity));
+ }
+
+ IEdmEntityType entityType = (IEdmEntityType)edmEntity.ActualEdmType;
+ return GetDataObjectType(GetEdmEntitySet(entityType).Name);
+ }
+
///
/// Получает список зарегистрированных в модели типов, которые являются дочерними к данному родительскому типу.
/// В список добавляется также сам родительский тип.
diff --git a/NewPlatform.Flexberry.ORM.ODataService/Model/DataObjectEdmTypeSettings.cs b/NewPlatform.Flexberry.ORM.ODataService/Model/DataObjectEdmTypeSettings.cs
index bcfcc3ef..4e4219a1 100644
--- a/NewPlatform.Flexberry.ORM.ODataService/Model/DataObjectEdmTypeSettings.cs
+++ b/NewPlatform.Flexberry.ORM.ODataService/Model/DataObjectEdmTypeSettings.cs
@@ -31,6 +31,11 @@ public sealed class DataObjectEdmTypeSettings
///
public View DefaultView { get; set; }
+ ///
+ /// View to be used instead of DefaultView on updates (Patch/Batch).
+ ///
+ public View UpdateView { get; set; }
+
///
/// The list of exposed details.
///
diff --git a/NewPlatform.Flexberry.ORM.ODataService/Model/DefaultDataObjectEdmModelBuilder.cs b/NewPlatform.Flexberry.ORM.ODataService/Model/DefaultDataObjectEdmModelBuilder.cs
index 63f84ab6..b6e3bd18 100644
--- a/NewPlatform.Flexberry.ORM.ODataService/Model/DefaultDataObjectEdmModelBuilder.cs
+++ b/NewPlatform.Flexberry.ORM.ODataService/Model/DefaultDataObjectEdmModelBuilder.cs
@@ -69,6 +69,11 @@ public class DefaultDataObjectEdmModelBuilder : IDataObjectEdmModelBuilder
///
public Func EntityPropertyNameBuilder { get; set; }
+ ///
+ /// Dictionary of views to be used to load objects on updates. Used to restrict properties for performance (all props are loaded if view is not specified).
+ ///
+ private Dictionary UpdateViews { get; set; }
+
private readonly PropertyInfo _keyProperty = Information.ExtractPropertyInfo(n => n.__PrimaryKey);
///
@@ -82,7 +87,8 @@ public DefaultDataObjectEdmModelBuilder(
IEnumerable searchAssemblies,
bool useNamespaceInEntitySetName = true,
PseudoDetailDefinitions pseudoDetailDefinitions = null,
- Dictionary additionalMapping = null)
+ Dictionary additionalMapping = null,
+ IEnumerable> updateViews = null)
{
_searchAssemblies = searchAssemblies ?? throw new ArgumentNullException(nameof(searchAssemblies), "Contract assertion not met: searchAssemblies != null");
_useNamespaceInEntitySetName = useNamespaceInEntitySetName;
@@ -94,6 +100,11 @@ public DefaultDataObjectEdmModelBuilder(
EntityPropertyNameBuilder = BuildEntityPropertyName;
EntityTypeNameBuilder = BuildEntityTypeName;
EntityTypeNamespaceBuilder = BuildEntityTypeNamespace;
+
+ if (updateViews != null)
+ {
+ SetUpdateView(updateViews);
+ }
}
///
@@ -173,6 +184,54 @@ public IPseudoDetailDefinition GetPseudoDetailDefinition(object pseudoDetail)
.FirstOrDefault();
}
+ ///
+ /// Change default views that would be used to load objects on updates.
+ ///
+ /// Should be called before MapDataObjectRoute.
+ /// Key - DataObject type, value - view to be used for objects of that type on updates.
+ private void SetUpdateView(IEnumerable> updateViews)
+ {
+ if (this.UpdateViews is null)
+ {
+ this.UpdateViews = new Dictionary();
+ }
+
+ if (updateViews != null)
+ {
+ foreach (KeyValuePair kvp in updateViews)
+ {
+ SetUpdateView(kvp.Key, kvp.Value);
+ }
+ }
+ }
+
+ ///
+ /// Change for a specific . Update view would be used to load these objects on updates.
+ ///
+ /// Should be called before MapDataObjectRoute.
+ /// DataObject type for which update view would be set.
+ /// Update view to be used for objects of type . Setting removes update view for the type.
+ private void SetUpdateView(Type dataObjectType, View updateView)
+ {
+ if (!typeof(DataObject).IsAssignableFrom(dataObjectType))
+ {
+ throw new ArgumentException("Update view can be set only for a DataObject.", nameof(dataObjectType));
+ }
+
+ if (updateView is null)
+ {
+ UpdateViews.Remove(dataObjectType);
+ return;
+ }
+
+ if (dataObjectType != updateView.DefineClassType)
+ {
+ throw new ArgumentException($"View from DataObject {updateView.DefineClassType} can not be set for a DataObject of type {dataObjectType}.", nameof(updateView));
+ }
+
+ UpdateViews[dataObjectType] = updateView;
+ }
+
///
/// Adds the property for exposing.
///
@@ -238,12 +297,21 @@ private void AddDataObjectWithHierarchy(DataObjectEdmMetadata meta, Type dataObj
AddDataObjectWithHierarchy(meta, baseType);
+ // Extract user-defined update view:
+ View updateView = null;
+ if (UpdateViews != null)
+ {
+ UpdateViews.TryGetValue(dataObjectType, out updateView);
+ }
+
var typeSettings = meta[dataObjectType] = new DataObjectEdmTypeSettings
{
EnableCollection = true,
CollectionName = EntitySetNameBuilder(dataObjectType),
- DefaultView = DynamicView.Create(dataObjectType, null).View
+ DefaultView = DynamicView.Create(dataObjectType, null).View,
+ UpdateView = updateView,
};
+
AddProperties(dataObjectType, typeSettings);
if (typeSettings.KeyType != null)
meta[baseType].KeyType = null;
diff --git a/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CRUD/Update/ModifyDataTest.cs b/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CRUD/Update/ModifyDataTest.cs
index d0592622..ce6ed159 100644
--- a/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CRUD/Update/ModifyDataTest.cs
+++ b/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CRUD/Update/ModifyDataTest.cs
@@ -1605,5 +1605,165 @@ public void UpdateDetailAndDetailTest()
}
});
}
+
+
+ ///
+ /// Тест на изменение ссылки.
+ ///
+ [Fact]
+ public void MasterChangeTest()
+ {
+ ActODataService(args =>
+ {
+ // Создаем объект данных, который потом будем обновлять, и добавляем в базу обычным сервисом данных.
+ Страна страна1 = new Страна { Название = "Страна1" };
+ Страна страна2 = new Страна { Название = "Россия" };
+ args.DataService.UpdateObject(страна1);
+ args.DataService.UpdateObject(страна2);
+
+ Лес лес = new Лес { Название = "Тайга", Площадь = 2000, Страна = страна1 };
+ args.DataService.UpdateObject(лес);
+
+ // Обновляем ссылку.
+ лес.Страна = страна2;
+
+ // Представление, по которому будем обновлять.
+ string[] лесPropertiesNames =
+ {
+ Information.ExtractPropertyPath<Лес>(x => x.__PrimaryKey),
+ };
+ var лесDynamicView = new View(new ViewAttribute("лесDynamicView", лесPropertiesNames), typeof(Лес));
+
+ // Преобразуем объект данных в JSON-строку.
+ string requestJsonDataЛес = лес.ToJson(лесDynamicView, args.Token.Model);
+
+ // Добавляем в payload информацию, что поменяли ссылку на страну.
+ var requestJsonData = ODataHelper.AddEntryRelationship(requestJsonDataЛес, лесDynamicView, args.Token.Model, страна2, nameof(Лес.Страна));
+
+ // Получаем адрес для PATCH запроса.
+ var requestUrl = ODataHelper.GetRequestUrl(args.Token.Model, лес);
+
+ // Обращаемся к OData-сервису и обрабатываем ответ, в теле запроса передаем обновляемый объект в формате JSON.
+ using (HttpResponseMessage response = args.HttpClient.PatchAsJsonStringAsync(requestUrl, requestJsonData).Result)
+ {
+ // Убедимся, что запрос завершился успешно (тело ответа д.б. пустым при отсутствии ошибок обновления).
+ Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
+
+ // Проверяем что объект данных был обновлен в базе, причем только по переданным атрибутам.
+ Лес updatedЛес = new Лес { __PrimaryKey = лес.__PrimaryKey };
+ args.DataService.LoadObject(updatedЛес);
+
+ Assert.Equal(лес.Страна.__PrimaryKey.ToString(), updatedЛес.Страна.__PrimaryKey.ToString());
+ }
+ });
+ }
+
+ ///
+ /// Тест на изменение агрегатора у детейла.
+ ///
+ [Fact]
+ public void AggregatorChangeTest()
+ {
+ ActODataService(args =>
+ {
+ // Создаем объекты данных, которые потом будем обновлять, и добавляем в базу обычным сервисом данных.
+ Медведь медведь1 = new Медведь { ПорядковыйНомер = 1 };
+ Медведь медведь2 = new Медведь { ПорядковыйНомер = 2 };
+ args.DataService.UpdateObject(медведь1);
+ args.DataService.UpdateObject(медведь2);
+
+ Берлога берлога1 = new Берлога { Наименование = "Берлога1", Медведь = медведь1 };
+ Берлога берлога2 = new Берлога { Наименование = "Берлога2", Медведь = медведь1 };
+ Берлога берлога3 = new Берлога { Наименование = "Берлога3", Медведь = медведь1 };
+ args.DataService.UpdateObject(берлога1);
+ args.DataService.UpdateObject(берлога2);
+ args.DataService.UpdateObject(берлога3);
+
+ // Обновляем ссылку.
+ берлога1.Медведь = медведь2;
+
+ // Представление, по которому будем обновлять.
+ string[] берлогаPropertiesNames =
+ {
+ Information.ExtractPropertyPath<Берлога>(x => x.__PrimaryKey),
+ };
+ var берлогаDynamicView = new View(new ViewAttribute("берлогаDynamicView", берлогаPropertiesNames), typeof(Берлога));
+
+ // Преобразуем объект данных в JSON-строку.
+ string requestJsonData = берлога1.ToJson(берлогаDynamicView, args.Token.Model);
+
+ // Добавляем в payload информацию, что поменяли ссылку на медведя.
+ requestJsonData = ODataHelper.AddEntryRelationship(requestJsonData, берлогаDynamicView, args.Token.Model, медведь2, nameof(Берлога.Медведь));
+
+ // Формируем URL запроса к OData-сервису (с идентификатором изменяемой сущности).
+ var requestUrl = ODataHelper.GetRequestUrl(args.Token.Model, берлога1);
+
+ // Обращаемся к OData-сервису и обрабатываем ответ, в теле запроса передаем обновляемый объект в формате JSON.
+ using (HttpResponseMessage response = args.HttpClient.PatchAsJsonStringAsync(requestUrl, requestJsonData).Result)
+ {
+ // Убедимся, что запрос завершился успешно (тело ответа д.б. пустым при отсутствии ошибок обновления).
+ Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
+
+ // Проверяем что объект данных был обновлен в базе, причем только по переданным атрибутам.
+ Берлога updatedБерлога = new Берлога { __PrimaryKey = берлога1.__PrimaryKey };
+ args.DataService.LoadObject(updatedБерлога);
+
+ Assert.Equal(берлога1.Медведь.__PrimaryKey.ToString(), updatedБерлога.Медведь.__PrimaryKey.ToString());
+ }
+ });
+ }
+
+ ///
+ /// Проверка изменения сложного агрегатора (у которого есть ещё ссылки на другие мастера).
+ ///
+ [Fact]
+ public void ComplexAggregatorChangeTest()
+ {
+ ActODataService(args =>
+ {
+ LegoDevice device1 = new LegoDevice { BlockId = 1, Name = "First" };
+ LegoDevice device2 = new LegoDevice { BlockId = 2, Name = "Second" };
+ LegoDevice device3 = new LegoDevice { BlockId = 3, Name = "Third" };
+ args.DataService.UpdateObject(device1);
+ args.DataService.UpdateObject(device2);
+ args.DataService.UpdateObject(device3);
+
+ // Создаем объекты данных, которые потом будем обновлять, и добавляем в базу обычным сервисом данных.
+ LegoPatent patent = new LegoPatent { Description = "Patent A", BaseLegoBlock = device1 };
+ args.DataService.UpdateObject(patent);
+
+ // Обновляем ссылку на агрегатора.
+ patent.BaseLegoBlock = device2;
+
+ // Представление, по которому будем обновлять.
+ string[] patentPropertiesNames =
+ {
+ Information.ExtractPropertyPath(x => x.__PrimaryKey),
+ };
+ var patentDynamicView = new View(new ViewAttribute("patentDynamicView", patentPropertiesNames), typeof(LegoPatent));
+
+ // Преобразуем объект данных в JSON-строку.
+ string requestJsonData = patent.ToJson(patentDynamicView, args.Token.Model);
+
+ // Добавляем в payload информацию, что поменяли ссылку на агрегатора.
+ requestJsonData = ODataHelper.AddEntryRelationship(requestJsonData, patentDynamicView, args.Token.Model, device2, nameof(LegoPatent.BaseLegoBlock));
+
+ // Формируем URL запроса к OData-сервису (с идентификатором изменяемой сущности).
+ var requestUrl = ODataHelper.GetRequestUrl(args.Token.Model, patent);
+
+ // Обращаемся к OData-сервису и обрабатываем ответ, в теле запроса передаем обновляемый объект в формате JSON.
+ using (HttpResponseMessage response = args.HttpClient.PatchAsJsonStringAsync(requestUrl, requestJsonData).Result)
+ {
+ // Убедимся, что запрос завершился успешно (тело ответа д.б. пустым при отсутствии ошибок обновления).
+ Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
+
+ // Проверяем что объект данных был обновлен в базе, причем только по переданным атрибутам.
+ LegoPatent updatedLegoPatent = new LegoPatent { __PrimaryKey = patent.__PrimaryKey };
+ args.DataService.LoadObject(updatedLegoPatent);
+
+ Assert.Equal(patent.BaseLegoBlock.__PrimaryKey.ToString(), updatedLegoPatent.BaseLegoBlock.__PrimaryKey.ToString());
+ }
+ });
}
}
+}
diff --git a/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CRUD/Update/UpdateViewsTest.cs b/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CRUD/Update/UpdateViewsTest.cs
new file mode 100644
index 00000000..2979cc0d
--- /dev/null
+++ b/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CRUD/Update/UpdateViewsTest.cs
@@ -0,0 +1,77 @@
+#if NETCOREAPP
+namespace NewPlatform.Flexberry.ORM.ODataService.Tests.CRUD.Update
+{
+ using System;
+ using System.Net;
+ using System.Net.Http;
+
+ using ICSSoft.STORMNET;
+ using NewPlatform.Flexberry.ORM.ODataService.Tests.Extensions;
+ using NewPlatform.Flexberry.ORM.ODataService.Tests.Helpers;
+
+ using Xunit;
+ using Xunit.Abstractions;
+
+ ///
+ /// Тесты для проверки работы UpdateViews.
+ ///
+ public class UpdateViewsTest : BaseODataServiceIntegratedTest
+ {
+ ///
+ /// Конструктор по-умолчанию.
+ ///
+ /// Фабрика для приложения.
+ /// Вывод диагностической информации по тестам.
+ public UpdateViewsTest(CustomWebApplicationFactory factory, ITestOutputHelper output)
+ : base(factory, output)
+ {
+
+ }
+
+ ///
+ /// Проверка работы UpdateView - случай когда в UpdateView не включен мастер.
+ ///
+ [Fact]
+ public void UpdateViewNoMastersTest()
+ {
+ ActODataService(args =>
+ {
+ // Создаем объекты данных, которые потом будем обновлять, и добавляем в базу обычным сервисом данных.
+ Медведь медведь1 = new Медведь { ПорядковыйНомер = 1 };
+ Медведь медведь2 = new Медведь { ПорядковыйНомер = 2 };
+ args.DataService.UpdateObject(медведь1);
+ args.DataService.UpdateObject(медведь2);
+
+ Берлога берлога1 = new Берлога { Наименование = "Берлога1", Медведь = медведь1 };
+ Берлога берлога2 = new Берлога { Наименование = "Берлога2", Медведь = медведь1 };
+ Берлога берлога3 = new Берлога { Наименование = "Берлога3", Медведь = медведь1 };
+ args.DataService.UpdateObject(берлога1);
+ args.DataService.UpdateObject(берлога2);
+ args.DataService.UpdateObject(берлога3);
+
+ // Обновляем ссылку.
+ берлога1.Медведь = медведь2;
+
+ // Представление, по которому будем обновлять.
+ string[] берлогаPropertiesNames =
+ {
+ Information.ExtractPropertyPath<Берлога>(x => x.__PrimaryKey),
+ };
+ var берлогаDynamicView = new View(new ViewAttribute("берлогаDynamicView", берлогаPropertiesNames), typeof(Берлога));
+
+ // Преобразуем объект данных в JSON-строку.
+ string requestJsonData = берлога1.ToJson(берлогаDynamicView, args.Token.Model);
+
+ // Добавляем в payload информацию, что поменяли ссылку на медведя.
+ requestJsonData = ODataHelper.AddEntryRelationship(requestJsonData, берлогаDynamicView, args.Token.Model, медведь2, nameof(Берлога.Медведь));
+
+ // Формируем URL запроса к OData-сервису (с идентификатором изменяемой сущности).
+ var requestUrl = ODataHelper.GetRequestUrl(args.Token.Model, берлога1);
+
+ // Сейчас обновление мастеров не поддерживается.
+ Assert.Throws(() => args.HttpClient.PatchAsJsonStringAsync(requestUrl, requestJsonData).Result); // Если падает Exception, значит представление поменялось и работает.
+ });
+ }
+ }
+}
+#endif
diff --git a/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CodeGen/NewPlatform.Flexberry.ORM.ODataService.Tests.crp b/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CodeGen/NewPlatform.Flexberry.ORM.ODataService.Tests.crp
index ebb6a638..05565b5b 100644
--- a/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CodeGen/NewPlatform.Flexberry.ORM.ODataService.Tests.crp
+++ b/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/CodeGen/NewPlatform.Flexberry.ORM.ODataService.Tests.crp
@@ -1,1147 +1,1164 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/Helpers/ODataHelper.cs b/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/Helpers/ODataHelper.cs
new file mode 100644
index 00000000..ea2100be
--- /dev/null
+++ b/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/Helpers/ODataHelper.cs
@@ -0,0 +1,47 @@
+using ICSSoft.STORMNET;
+using ICSSoft.STORMNET.KeyGen;
+using NewPlatform.Flexberry.ORM.ODataService.Model;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NewPlatform.Flexberry.ORM.ODataService.Tests.Helpers
+{
+ public class ODataHelper
+ {
+ ///
+ /// Добавить запись об изменении ссылки в OData Payload.
+ ///
+ /// Исходный payload.
+ /// Представление исходного объекта.
+ /// EDM модель.
+ /// Новый объект данных (по ссылке).
+ /// Ссылка на новый объект данных.
+ /// Новый OData Payload.
+ public static string AddEntryRelationship(string requestJsonData, View view, DataObjectEdmModel model, DataObject dataObject, string relationName)
+ {
+ DataObjectDictionary objJsonМедв = DataObjectDictionary.Parse(requestJsonData, view, model);
+
+ objJsonМедв.Add(
+ $"{relationName}@odata.bind",
+ string.Format(
+ "{0}({1})",
+ model.GetEdmEntitySet(dataObject.GetType()).Name,
+ ((KeyGuid)dataObject.__PrimaryKey).Guid.ToString("D")));
+
+ var result = objJsonМедв.Serialize();
+ return result;
+ }
+
+ ///
+ /// Получить URL для запроса к OData.
+ ///
+ /// EDM модель.
+ /// Объект (по которому выполняется запрос).
+ /// URL запроса к OData.
+ public static string GetRequestUrl(DataObjectEdmModel model, DataObject dataObject)
+ => string.Format("http://localhost/odata/{0}({1})", model.GetEdmEntitySet(dataObject.GetType()).Name, ((KeyGuid)dataObject.__PrimaryKey).Guid.ToString());
+ }
+}
diff --git a/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/Startups/UpdateViewsTestStartup.cs b/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/Startups/UpdateViewsTestStartup.cs
new file mode 100644
index 00000000..d65fbf94
--- /dev/null
+++ b/Tests/NewPlatform.Flexberry.ORM.ODataService.Tests/Startups/UpdateViewsTestStartup.cs
@@ -0,0 +1,76 @@
+#if NETCOREAPP
+namespace NewPlatform.Flexberry.ORM.ODataService.Tests
+{
+ using System;
+ using System.Collections.Generic;
+ using ICSSoft.Services;
+ using ICSSoft.STORMNET;
+ using IIS.Caseberry.Logging.Objects;
+ using Microsoft.AspNetCore.Builder;
+ using Microsoft.AspNetCore.Hosting;
+ using Microsoft.AspNetCore.Routing;
+ using Microsoft.Extensions.Configuration;
+ using NewPlatform.Flexberry.ORM.ODataService;
+ using NewPlatform.Flexberry.ORM.ODataService.Extensions;
+ using NewPlatform.Flexberry.ORM.ODataService.Model;
+ using NewPlatform.Flexberry.ORM.ODataService.WebApi.Extensions;
+ using NewPlatform.Flexberry.Services;
+ using ODataServiceSample.AspNetCore;
+ using Unity;
+
+ ///
+ /// Startup for testing UpdateView configuration.
+ ///
+ public class UpdateViewsTestStartup : Startup
+ {
+ ///
+ /// Initialize new instance of TestStartup.
+ ///
+ /// Configuration for new instance.
+ public UpdateViewsTestStartup(IConfiguration configuration)
+ : base(configuration)
+ {
+ }
+
+ ///
+ public override void Configure(IApplicationBuilder app, IHostingEnvironment env)
+ {
+ IUnityContainer unityContainer = UnityFactory.GetContainer();
+ unityContainer.RegisterInstance(env);
+
+ app.UseMiddleware();
+
+ app.UseMvc(builder =>
+ {
+ builder.MapRoute("Lock", "api/lock/{action}/{dataObjectId}", new { controller = "Lock" });
+ builder.MapFileRoute();
+ });
+
+ app.UseODataService(builder =>
+ {
+ IUnityContainer container = UnityFactory.GetContainer();
+
+ var assemblies = new[]
+ {
+ typeof(Медведь).Assembly,
+ typeof(ApplicationLog).Assembly,
+ typeof(UserSetting).Assembly,
+ typeof(Lock).Assembly,
+ };
+
+ PseudoDetailDefinitions pseudoDetailDefinitions = (PseudoDetailDefinitions)container.Resolve(typeof(PseudoDetailDefinitions));
+ var updateViews = new Dictionary()
+ {
+ { typeof(Медведь), Медведь.Views.МедведьUpdateView },
+ { typeof(Берлога), Берлога.Views.БерлогаUpdateView },
+ };
+ var modelBuilder = new DefaultDataObjectEdmModelBuilder(assemblies, false, pseudoDetailDefinitions, updateViews: updateViews);
+
+ var token = builder.MapDataObjectRoute(modelBuilder);
+
+ container.RegisterInstance(typeof(ManagementToken), token);
+ });
+ }
+ }
+}
+#endif
diff --git "a/Tests/Objects/\320\221\320\265\321\200\320\273\320\276\320\263\320\260.cs" "b/Tests/Objects/\320\221\320\265\321\200\320\273\320\276\320\263\320\260.cs"
index 1dd229ac..7dcc108c 100644
--- "a/Tests/Objects/\320\221\320\265\321\200\320\273\320\276\320\263\320\260.cs"
+++ "b/Tests/Objects/\320\221\320\265\321\200\320\273\320\276\320\263\320\260.cs"
@@ -50,6 +50,11 @@ namespace NewPlatform.Flexberry.ORM.ODataService.Tests
"Сертификат",
"СертификатСтрока"})]
[MasterViewDefineAttribute("БерлогаE", "ЛесРасположения", ICSSoft.STORMNET.LookupTypeEnum.Standard, "", "Название")]
+ [View("БерлогаUpdateView", new string[] {
+ "Наименование as \'Наименование\'",
+ "Комфортность as \'Комфортность\'",
+ "Заброшена as \'Заброшена\'",
+ "ПолеБС"})]
public class Берлога : ICSSoft.STORMNET.DataObject
{
@@ -393,6 +398,17 @@ public static ICSSoft.STORMNET.View БерлогаE
return ICSSoft.STORMNET.Information.GetView("БерлогаE", typeof(NewPlatform.Flexberry.ORM.ODataService.Tests.Берлога));
}
}
+
+ ///
+ /// Представление для тестов UpdateView (без мастеров и детейлов).
+ ///
+ public static ICSSoft.STORMNET.View БерлогаUpdateView
+ {
+ get
+ {
+ return ICSSoft.STORMNET.Information.GetView("БерлогаUpdateView", typeof(NewPlatform.Flexberry.ORM.ODataService.Tests.Берлога));
+ }
+ }
}
}
@@ -419,7 +435,7 @@ public class DetailArrayOfБерлога : ICSSoft.STORMNET.DetailArray
///
/// Adds object with type Берлога.
///
- public DetailArrayOfБерлога(NewPlatform.Flexberry.ORM.ODataService.Tests.Медведь fМедведь) :
+ public DetailArrayOfБерлога(NewPlatform.Flexberry.ORM.ODataService.Tests.Медведь fМедведь) :
base(typeof(Берлога), ((ICSSoft.STORMNET.DataObject)(fМедведь)))
{
}
diff --git "a/Tests/Objects/\320\234\320\265\320\264\320\262\320\265\320\264\321\214.cs" "b/Tests/Objects/\320\234\320\265\320\264\320\262\320\265\320\264\321\214.cs"
index 60331c62..854f42cf 100644
--- "a/Tests/Objects/\320\234\320\265\320\264\320\262\320\265\320\264\321\214.cs"
+++ "b/Tests/Objects/\320\234\320\265\320\264\320\262\320\265\320\264\321\214.cs"
@@ -72,6 +72,13 @@ namespace NewPlatform.Flexberry.ORM.ODataService.Tests
"ЛесОбитания.Название as \'Название\'"})]
[View("МедведьShort", new string[] {
"ПорядковыйНомер as \'Порядковый номер\'"})]
+ [View("МедведьUpdateView", new string[] {
+ "ПорядковыйНомер as \'Порядковый номер\'",
+ "Вес as \'Вес\'",
+ "ЦветГлаз as \'Цвет глаз\'",
+ "Пол as \'Пол\'",
+ "ДатаРождения as \'Дата рождения\'",
+ "ПолеБС"})]
[View("МедведьСДелейломИВычислимымСвойством", new string[] {
"ПорядковыйНомер as \'Порядковый номер\'",
"Вес as \'Вес\'",
@@ -724,6 +731,17 @@ public static ICSSoft.STORMNET.View МедведьShort
}
}
+ ///
+ /// Представление для тестов UpdateView (без мастеров и детейлов).
+ ///
+ public static ICSSoft.STORMNET.View МедведьUpdateView
+ {
+ get
+ {
+ return ICSSoft.STORMNET.Information.GetView("МедведьUpdateView", typeof(NewPlatform.Flexberry.ORM.ODataService.Tests.Медведь));
+ }
+ }
+
///
/// "МедведьСДелейломИВычислимымСвойством" view.
///