Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions src/VirtoCommerce.Platform.Data/GenericCrud/CrudService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Primitives;
Expand Down Expand Up @@ -32,6 +33,7 @@
private readonly IEventPublisher _eventPublisher;
private readonly IPlatformMemoryCache _platformMemoryCache;
private readonly Func<IRepository> _repositoryFactory;
private readonly bool _isToModelOverridden;

/// <summary>
/// Construct new CrudService
Expand All @@ -44,6 +46,10 @@
_repositoryFactory = repositoryFactory;
_platformMemoryCache = platformMemoryCache;
_eventPublisher = eventPublisher;

_isToModelOverridden = GetType()
.GetMethod(nameof(ToModel), BindingFlags.Instance | BindingFlags.NonPublic, [typeof(TEntity)])

Check warning on line 51 in src/VirtoCommerce.Platform.Data/GenericCrud/CrudService.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Make sure that this accessibility bypass is safe here.

See more on https://sonarcloud.io/project/issues?id=VirtoCommerce_vc-platform&issues=AZzm8BTsgS-m3yv4obmQ&open=AZzm8BTsgS-m3yv4obmQ&pullRequest=2988
?.DeclaringType != typeof(CrudService<TModel, TEntity, TChangingEvent, TChangedEvent>);
}

/// <summary>
Expand Down Expand Up @@ -75,7 +81,7 @@
{
using var repository = _repositoryFactory();

// Disable DBContext change tracking for better performance
// Disable DBContext change tracking for better performance
repository.DisableChangesTracking();

var entities = await LoadEntities(repository, ids, responseGroup);
Expand All @@ -91,7 +97,7 @@
protected virtual IList<TModel> ProcessModels(IList<TEntity> entities, string responseGroup)
{
return entities
?.Select(x => ProcessModel(responseGroup, x, ToModel(x)))
?.Select(x => ProcessModel(responseGroup, x, ToModel(x, model: null)))
.ToList();
}

Expand Down Expand Up @@ -196,7 +202,7 @@
// https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#detectchanges-honors-store-generated-key-values
repository.TrackModifiedAsAddedForNewChildEntities(originalEntity);

var originalModel = ToModel(originalEntity);
var originalModel = ToModel(originalEntity, model: null);
originalModels.Add(originalModel);
changedEntries.Add(new GenericChangedEntry<TModel>(model, originalModel, EntryState.Modified));
modifiedEntity.Patch(originalEntity);
Expand Down Expand Up @@ -226,7 +232,8 @@

foreach (var (changedEntry, i) in changedEntries.Select((x, i) => (x, i)))
{
changedEntry.NewEntry = ToModel(changedEntities[i]);
// Sync database-generated values back to the original models
changedEntry.NewEntry = ToModel(changedEntities[i], changedEntry.NewEntry);
}

await AfterSaveChangesAsync(models, changedEntries);
Expand Down Expand Up @@ -330,6 +337,22 @@
GenericSearchCachingRegion<TModel>.ExpireRegion();
}

protected virtual TModel ToModel(TEntity entity, TModel model)
{
// Call the obsolete method temporarily if it has been overridden in a derived class, to avoid breaking changes.
if (_isToModelOverridden)
{
#pragma warning disable VC0014 // Type or member is obsolete
return ToModel(entity);
#pragma warning restore VC0014 // Type or member is obsolete
}

model ??= AbstractTypeFactory<TModel>.TryCreateInstance();

return entity.ToModel(model);
}

[Obsolete("Use ToModel(entity, model)", DiagnosticId = "VC0014", UrlFormat = "https://docs.virtocommerce.org/products/products-virto3-versions")]
protected virtual TModel ToModel(TEntity entity)
{
return entity.ToModel();
Expand Down
Loading