Compare commits

...

4 Commits

Author SHA1 Message Date
Sebastiaan Janssen bcb26c4065 Bump version to 7.12.4 2018-11-01 13:05:12 +01:00
Shannon 0d165db687 Slight refactor and cleanup
(cherry picked from commit 1429053681)
2018-11-01 13:00:41 +01:00
Claus 76aaafd852 whitespace
(cherry picked from commit c0109e0531)
2018-11-01 13:00:32 +01:00
Claus 77101783f7 adds internal methods for getting media entities through the entity repository/service without fetching all property data.
ensures the trees use this method to avoid fetching property data in the media tree.

(cherry picked from commit c4ee9abe68)
2018-11-01 13:00:17 +01:00
9 changed files with 107 additions and 34 deletions
+2 -2
View File
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.12.3")]
[assembly: AssemblyInformationalVersion("7.12.3")]
[assembly: AssemblyFileVersion("7.12.4")]
[assembly: AssemblyInformationalVersion("7.12.4")]
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.12.3");
private static readonly Version Version = new Version("7.12.4");
/// <summary>
/// Gets the current version of Umbraco.
@@ -140,6 +140,9 @@ namespace Umbraco.Core.Persistence.Factories
/// <returns></returns>
internal static bool TryMatch(string text, out string mediaPath)
{
//TODO: In v8 we should allow exposing this via the property editor in a much nicer way so that the property editor
// can tell us directly what any URL is for a given property if it contains an asset
mediaPath = null;
if (string.IsNullOrWhiteSpace(text))
@@ -155,4 +158,4 @@ namespace Umbraco.Core.Persistence.Factories
return true;
}
}
}
}
@@ -331,14 +331,23 @@ namespace Umbraco.Core.Persistence.Repositories
return list;
}
/// <summary>
/// Gets entities by query.
/// </summary>
/// <param name="query"></param>
/// <param name="objectTypeId"></param>
/// <returns></returns>
/// <remarks>
/// Note that this will also fetch all property data for media items, which can cause performance problems
/// when used without paging, in sites with large amounts of data in cmsPropertyData.
/// </remarks>
public virtual IEnumerable<IUmbracoEntity> GetByQuery(IQuery<IUmbracoEntity> query, Guid objectTypeId)
{
bool isContent = objectTypeId == Constants.ObjectTypes.DocumentGuid || objectTypeId == Constants.ObjectTypes.DocumentBlueprintGuid;
bool isMedia = objectTypeId == Constants.ObjectTypes.MediaGuid;
var isContent = objectTypeId == Constants.ObjectTypes.DocumentGuid || objectTypeId == Constants.ObjectTypes.DocumentBlueprintGuid;
var isMedia = objectTypeId == Constants.ObjectTypes.MediaGuid;
var sqlClause = GetBaseWhere(GetBase, isContent, isMedia, null, objectTypeId);
var translator = new SqlTranslator<IUmbracoEntity>(sqlClause, query);
var entitySql = translator.Translate();
@@ -364,22 +373,49 @@ namespace Umbraco.Core.Persistence.Repositories
}
else
{
//use dynamic so that we can get ALL properties from the SQL so we can chuck that data into our AdditionalData
var finalSql = entitySql.Append(GetGroupBy(isContent, false));
//query = read forward data reader, do not load everything into mem
var dtos = _work.Database.Query<dynamic>(finalSql);
var collection = new EntityDefinitionCollection();
foreach (var dto in dtos)
{
collection.AddOrUpdate(new EntityDefinition(factory, dto, isContent, false));
}
return collection.Select(x => x.BuildFromDynamic()).ToList();
return GetByQueryInternal(entitySql, isContent, isMedia);
}
}
/// <summary>
/// Gets entities by query without fetching property data.
/// </summary>
/// <param name="query"></param>
/// <param name="objectTypeId"></param>
/// <returns></returns>
/// <remarks>
/// This is supposed to be internal and can be used when getting all entities without paging, without causing
/// performance issues.
/// </remarks>
internal IEnumerable<IUmbracoEntity> GetMediaByQueryWithoutPropertyData(IQuery<IUmbracoEntity> query)
{
var sqlClause = GetBaseWhere(GetBase, false, true, null, UmbracoObjectTypes.Media.GetGuid());
var translator = new SqlTranslator<IUmbracoEntity>(sqlClause, query);
var entitySql = translator.Translate();
return GetByQueryInternal(entitySql, false, true);
}
internal IEnumerable<IUmbracoEntity> GetByQueryInternal(Sql entitySql, bool isContent, bool isMedia)
{
var factory = new UmbracoEntityFactory();
//use dynamic so that we can get ALL properties from the SQL so we can chuck that data into our AdditionalData
var finalSql = entitySql.Append(GetGroupBy(isContent, isMedia));
//query = read forward data reader, do not load everything into mem
var dtos = _work.Database.Query<dynamic>(finalSql);
var collection = new EntityDefinitionCollection();
foreach (var dto in dtos)
{
collection.AddOrUpdate(new EntityDefinition(factory, dto, isContent, isMedia));
}
return collection.Select(x => x.BuildFromDynamic()).ToList();
}
#endregion
#region Sql Statements
@@ -851,4 +887,4 @@ namespace Umbraco.Core.Persistence.Repositories
}
#endregion
}
}
}
+25 -7
View File
@@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Umbraco.Core.Cache;
using Umbraco.Core.CodeAnnotations;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
@@ -13,6 +11,7 @@ using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
@@ -287,16 +286,35 @@ namespace Umbraco.Core.Services
public virtual IEnumerable<IUmbracoEntity> GetChildren(int parentId, UmbracoObjectTypes umbracoObjectType)
{
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var query = Query<IUmbracoEntity>.Builder.Where(x => x.ParentId == parentId);
return repository.GetByQuery(query, objectTypeId);
}
}
/// <summary>
/// Gets a collection of children by the parent's Id and UmbracoObjectType without adding property data
/// </summary>
/// <param name="parentId">Id of the parent to retrieve children for</param>
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
internal IEnumerable<IUmbracoEntity> GetMediaChildrenWithoutPropertyData(int parentId)
{
var objectTypeId = UmbracoObjectTypes.Media.GetGuid();
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var query = Query<IUmbracoEntity>.Builder.Where(x => x.ParentId == parentId);
var contents = repository.GetByQuery(query, objectTypeId);
return contents;
// Not pretty having to cast the repository, but it is the only way to get to use an internal method that we
// do not want to make public on the interface. Unfortunately also prevents this from being unit tested.
// See this issue for details on why we need this:
// https://github.com/umbraco/Umbraco-CMS/issues/3457
return ((EntityRepository)repository).GetMediaByQueryWithoutPropertyData(query);
}
}
/// <summary>
/// Returns a paged collection of children
/// </summary>
@@ -781,4 +799,4 @@ namespace Umbraco.Core.Services
return node.NodeId;
}
}
}
}
+2 -2
View File
@@ -1035,9 +1035,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7123</DevelopmentServerPort>
<DevelopmentServerPort>7124</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7123</IISUrl>
<IISUrl>http://localhost:7124</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -207,6 +207,9 @@ namespace Umbraco.Web.Trees
return HasPathAccess(entity, queryStrings);
}
internal override IEnumerable<IUmbracoEntity> GetChildrenFromEntityService(int entityId)
=> Services.EntityService.GetChildren(entityId, UmbracoObjectType).ToList();
/// <summary>
/// Returns a collection of all menu items that can be on a content node
/// </summary>
@@ -1,7 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Http;
@@ -11,12 +10,12 @@ using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence;
using Umbraco.Web.Models.Trees;
using Umbraco.Web.WebApi.Filters;
using umbraco;
using umbraco.BusinessLogic.Actions;
using System.Globalization;
using Umbraco.Core.Services;
namespace Umbraco.Web.Trees
{
@@ -203,9 +202,16 @@ namespace Umbraco.Web.Trees
entityId = entity.Id;
}
return Services.EntityService.GetChildren(entityId, UmbracoObjectType).ToList();
return GetChildrenFromEntityService(entityId);
}
/// <summary>
/// Abstract method to fetch the entities from the entity service
/// </summary>
/// <param name="entityId"></param>
/// <returns></returns>
internal abstract IEnumerable<IUmbracoEntity> GetChildrenFromEntityService(int entityId);
/// <summary>
/// Returns true or false if the current user has access to the node based on the user's allowed start node (path) access
/// </summary>
+8 -1
View File
@@ -173,5 +173,12 @@ namespace Umbraco.Web.Trees
{
return _treeSearcher.ExamineSearch(Umbraco, query, UmbracoEntityTypes.Media, pageSize, pageIndex, out totalFound, searchFrom);
}
internal override IEnumerable<IUmbracoEntity> GetChildrenFromEntityService(int entityId)
// Not pretty having to cast the service, but it is the only way to get to use an internal method that we
// do not want to make public on the interface. Unfortunately also prevents this from being unit tested.
// See this issue for details on why we need this:
// https://github.com/umbraco/Umbraco-CMS/issues/3457
=> ((EntityService)Services.EntityService).GetMediaChildrenWithoutPropertyData(entityId).ToList();
}
}
}