Skip to content

Commit

Permalink
Возможность задать UpdateView + тесты
Browse files Browse the repository at this point in the history
  • Loading branch information
inaidanov authored and turbcool committed Mar 11, 2024
1 parent c356535 commit 173dc50
Show file tree
Hide file tree
Showing 12 changed files with 1,654 additions and 1,391 deletions.
230 changes: 115 additions & 115 deletions NewPlatform.Flexberry.ORM.ODataService.nuspec

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace NewPlatform.Flexberry.ORM.ODataService.Controllers
namespace NewPlatform.Flexberry.ORM.ODataService.Controllers
{
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -28,6 +28,8 @@
using System.Web.Http.Validation;
using NewPlatform.Flexberry.ORM.ODataService.Events;
using NewPlatform.Flexberry.ORM.ODataService.Handlers;
using Newtonsoft.Json.Linq;
using System.Web;
#endif
#if NETSTANDARD
using Microsoft.AspNet.OData.Formatter;
Expand All @@ -38,10 +40,10 @@
using NewPlatform.Flexberry.ORM.ODataService.Middleware;
#endif

/// <summary>
/// Определяет класс контроллера OData, который поддерживает запись и чтение данных с использованием OData формата.
/// </summary>
public partial class DataObjectController
/// <summary>
/// Определяет класс контроллера OData, который поддерживает запись и чтение данных с использованием OData формата.
/// </summary>
public partial class DataObjectController
{
/// <summary>
/// Метаданные файлов, временно загруженных в каталог файлового хранилища и привязанных к свойствам обрабатываемых объектов данных.
Expand Down Expand Up @@ -848,8 +850,41 @@ private static void AddObjectToUpdate(List<DataObject> objsToUpdate, DataObject
objsToUpdate.Insert(0, dataObject); // Добавляем объект в начало списка.
}

}
}
}

/// <summary>
/// Получить значение ключа у указанной сущности.
/// </summary>
/// <param name="edmEntity">Сущность.</param>
/// <returns>Значение ключа.</returns>
private object GetKey(EdmEntityObject edmEntity)
{
object key;

// Получим значение ключа.
IEdmEntityType entityType = (IEdmEntityType)edmEntity.ActualEdmType;
IEnumerable<IEdmProperty> entityProps = entityType.Properties();
var keyProperty = entityProps.FirstOrDefault(prop => prop.Name == _model.KeyPropertyName);
edmEntity.TryGetPropertyValue(keyProperty.Name, out key);

return key;
}

/// <summary>
/// Построение объекта данных по сущности OData без загрузки свойств и мастеров/детейлов. Загружен только первичный ключ.
/// </summary>
/// <param name="edmEntity">Сущность OData.</param>
/// <returns>Объект данных.</returns>
private DataObject GetDataObjectByEdmEntityLight(EdmEntityObject edmEntity)
{
var masterType = _model.GetDataObjectType(edmEntity);
var masterKey = GetKey(edmEntity);
var dataObject = (DataObject)Activator.CreateInstance(masterType);
dataObject.SetExistObjectPrimaryKey(masterKey);

return dataObject;
}

/// <summary>
/// Построение объекта данных по сущности OData.
Expand All @@ -867,21 +902,7 @@ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object ke
return null;
}

// Значение свойства.
object value;

// Получим значение ключа.
IEdmEntityType entityType = (IEdmEntityType)edmEntity.ActualEdmType;
IEnumerable<IEdmProperty> entityProps = entityType.Properties().ToList();
var keyProperty = entityProps.FirstOrDefault(prop => prop.Name == _model.KeyPropertyName);
if (key != null)
{
value = key;
}
else
{
edmEntity.TryGetPropertyValue(keyProperty.Name, out value);
}
key = key ?? GetKey(edmEntity);

// Загрузим объект из хранилища, если он там есть, или создадим, если нет, но только для POST.
// Тем самым гарантируем загруженность свойств при необходимости обновления и установку нужного статуса.
Expand All @@ -896,7 +917,7 @@ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object ke
view = _model.GetDataObjectDefaultView(objType);
}

DataObject obj = ReturnDataObject(objType, value, view);
DataObject obj = ReturnDataObject(objType, key, view);

// Добавляем объект в список для обновления, если там ещё нет объекта с таким ключом.
AddObjectToUpdate(dObjs, obj, endObject);
Expand All @@ -906,12 +927,17 @@ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object ke
IEnumerable<string> changedPropNames = edmEntity.GetChangedPropertyNames();

// Обрабатываем агрегатор первым.
IEdmEntityType entityType = (IEdmEntityType)edmEntity.ActualEdmType;
IEnumerable<IEdmProperty> entityProps = entityType.Properties().ToList();
List<IEdmProperty> changedProps = entityProps
.Where(ep => changedPropNames.Contains(ep.Name))
.OrderBy(ep => ep.Name != agregatorPropertyName)
.ToList();
foreach (var prop in changedProps)
{
object value;
edmEntity.TryGetPropertyValue(prop.Name, out value);

string dataObjectPropName;
try
{
Expand All @@ -931,8 +957,6 @@ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object ke
// Обработка мастеров и детейлов.
if (prop is EdmNavigationProperty navProp)
{
edmEntity.TryGetPropertyValue(prop.Name, out value);

EdmMultiplicity edmMultiplicity = navProp.TargetMultiplicity();

// Обработка мастеров.
Expand All @@ -942,11 +966,25 @@ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object ke
{
// Порядок вставки влияет на порядок отправки объектов в UpdateObjects это в свою очередь влияет на то, как срабатывают бизнес-серверы. Бизнес-сервер мастера должен сработать после, а агрегатора перед этим объектом.
bool insertIntoEnd = string.IsNullOrEmpty(agregatorPropertyName);
DataObject master = GetDataObjectByEdmEntity(edmMaster, null, dObjs, insertIntoEnd, useUpdateView);
bool masterOwnPropsUpdated = edmMaster.GetChangedPropertyNames().Any(propName => propName != _model.KeyPropertyName);
bool isAggregator = dataObjectPropName == agregatorPropertyName;
DataObject master = null;

Type masterType = _model.GetDataObjectType(edmEntity);
bool masterLightLoad = _model.IsMasterLightLoad(masterType);

if (masterLightLoad && !masterOwnPropsUpdated && !isAggregator)
{
master = GetDataObjectByEdmEntityLight(edmMaster); // здесь мастер не добавляется в dObjs (объекты на обновление) т.к. мы точно знаем что он будет в состоянии UnAltered
}
else
{
master = GetDataObjectByEdmEntity(edmMaster, null, dObjs, insertIntoEnd, useUpdateView);
}

Information.SetPropValueByName(obj, dataObjectPropName, master);

if (dataObjectPropName == agregatorPropertyName)
if (isAggregator)
{
master.AddDetail(obj);

Expand Down Expand Up @@ -1002,10 +1040,9 @@ private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object ke
else
{
// Обработка собственных свойств объекта (неключевых, т.к. ключ устанавливаем при начальной инициализации объекта obj).
if (prop.Name != keyProperty.Name)
if (prop.Name != _model.KeyPropertyName)
{
Type dataObjectPropertyType = Information.GetPropertyType(objType, dataObjectPropName);
edmEntity.TryGetPropertyValue(prop.Name, out value);

// Если тип свойства относится к одному из зарегистрированных провайдеров файловых свойств,
// значит свойство файловое, и его нужно обработать особым образом.
Expand Down
Loading

0 comments on commit 173dc50

Please sign in to comment.