Merge remote-tracking branch 'origin/v8/dev' into netcore/dev

# Conflicts:
#	src/SolutionInfo.cs
#	src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml
#	src/Umbraco.Web.UI/config/umbracoSettings.config
#	src/Umbraco.Web/Services/IconService.cs
This commit is contained in:
Bjarke Berg
2020-11-12 09:13:53 +01:00
41 changed files with 1165 additions and 207 deletions

View File

@@ -988,6 +988,81 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
}
/// <summary>
/// Inserts property values for the content entity
/// </summary>
/// <param name="entity"></param>
/// <param name="publishedVersionId"></param>
/// <param name="edited"></param>
/// <param name="editedCultures"></param>
/// <remarks>
/// Used when creating a new entity
/// </remarks>
protected void InsertPropertyValues(TEntity entity, int publishedVersionId, out bool edited, out HashSet<string> editedCultures)
{
// persist the property data
var propertyDataDtos = PropertyFactory.BuildDtos(entity.ContentType.Variations, entity.VersionId, publishedVersionId, entity.Properties, LanguageRepository, out edited, out editedCultures);
foreach (var propertyDataDto in propertyDataDtos)
{
Database.Insert(propertyDataDto);
}
// TODO: we can speed this up: Use BulkInsert and then do one SELECT to re-retrieve the property data inserted with assigned IDs.
// This is a perfect thing to benchmark with Benchmark.NET to compare perf between Nuget releases.
}
/// <summary>
/// Used to atomically replace the property values for the entity version specified
/// </summary>
/// <param name="entity"></param>
/// <param name="versionId"></param>
/// <param name="publishedVersionId"></param>
/// <param name="edited"></param>
/// <param name="editedCultures"></param>
protected void ReplacePropertyValues(TEntity entity, int versionId, int publishedVersionId, out bool edited, out HashSet<string> editedCultures)
{
// Replace the property data.
// Lookup the data to update with a UPDLOCK (using ForUpdate()) this is because we need to be atomic
// and handle DB concurrency. Doing a clear and then re-insert is prone to concurrency issues.
var propDataSql = SqlContext.Sql().Select("*").From<PropertyDataDto>().Where<PropertyDataDto>(x => x.VersionId == versionId).ForUpdate();
var existingPropData = Database.Fetch<PropertyDataDto>(propDataSql);
var propertyTypeToPropertyData = new Dictionary<(int propertyTypeId, int versionId, int? languageId, string segment), PropertyDataDto>();
var existingPropDataIds = new List<int>();
foreach (var p in existingPropData)
{
existingPropDataIds.Add(p.Id);
propertyTypeToPropertyData[(p.PropertyTypeId, p.VersionId, p.LanguageId, p.Segment)] = p;
}
var propertyDataDtos = PropertyFactory.BuildDtos(entity.ContentType.Variations, entity.VersionId, publishedVersionId, entity.Properties, LanguageRepository, out edited, out editedCultures);
foreach (var propertyDataDto in propertyDataDtos)
{
// Check if this already exists and update, else insert a new one
if (propertyTypeToPropertyData.TryGetValue((propertyDataDto.PropertyTypeId, propertyDataDto.VersionId, propertyDataDto.LanguageId, propertyDataDto.Segment), out var propData))
{
propertyDataDto.Id = propData.Id;
Database.Update(propertyDataDto);
}
else
{
// TODO: we can speed this up: Use BulkInsert and then do one SELECT to re-retrieve the property data inserted with assigned IDs.
// This is a perfect thing to benchmark with Benchmark.NET to compare perf between Nuget releases.
Database.Insert(propertyDataDto);
}
// track which ones have been processed
existingPropDataIds.Remove(propertyDataDto.Id);
}
// For any remaining that haven't been processed they need to be deleted
if (existingPropDataIds.Count > 0)
{
Database.Execute(SqlContext.Sql().Delete<PropertyDataDto>().WhereIn<PropertyDataDto>(x => x.Id, existingPropDataIds));
}
}
private class NodeIdKey
{
[Column("id")]