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.
This commit is contained in:
@@ -331,24 +331,49 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets entities by query.
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="objectTypeId"></param>
|
||||
/// <returns></returns>
|
||||
public virtual IEnumerable<IUmbracoEntity> GetByQuery(IQuery<IUmbracoEntity> query, Guid objectTypeId)
|
||||
{
|
||||
return GetByQueryInternal(query, objectTypeId, true);
|
||||
}
|
||||
|
||||
bool isContent = objectTypeId == Constants.ObjectTypes.DocumentGuid || objectTypeId == Constants.ObjectTypes.DocumentBlueprintGuid;
|
||||
bool isMedia = objectTypeId == Constants.ObjectTypes.MediaGuid;
|
||||
/// <summary>
|
||||
/// Gets entities by query without fetching property data.
|
||||
/// This is supposed to be internal and can be used when getting all entities without paging, without causing
|
||||
/// performance issues.
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="objectTypeId"></param>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<IUmbracoEntity> GetByQueryWithoutPropertyData(IQuery<IUmbracoEntity> query, Guid objectTypeId)
|
||||
{
|
||||
return GetByQueryInternal(query, objectTypeId, false);
|
||||
}
|
||||
|
||||
internal IEnumerable<IUmbracoEntity> GetByQueryInternal(IQuery<IUmbracoEntity> query, Guid objectTypeId, bool includePropertyData)
|
||||
{
|
||||
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();
|
||||
|
||||
var factory = new UmbracoEntityFactory();
|
||||
|
||||
if (isMedia)
|
||||
if (isMedia && includePropertyData)
|
||||
{
|
||||
var wheres = query.GetWhereClauses().ToArray();
|
||||
|
||||
var mediaSql = GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false)), sql =>
|
||||
var mediaSql = GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, isMedia, false)), sql =>
|
||||
{
|
||||
//adds the additional filters
|
||||
foreach (var whereClause in wheres)
|
||||
@@ -365,21 +390,21 @@ 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));
|
||||
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, false));
|
||||
collection.AddOrUpdate(new EntityDefinition(factory, dto, isContent, isMedia));
|
||||
}
|
||||
return collection.Select(x => x.BuildFromDynamic()).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Sql Statements
|
||||
|
||||
@@ -851,4 +876,4 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -285,15 +284,37 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="umbracoObjectType">UmbracoObjectType of the children to retrieve</param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
|
||||
public virtual IEnumerable<IUmbracoEntity> GetChildren(int parentId, UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
return GetChildrenInternal(parentId, umbracoObjectType, true);
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// <param name="umbracoObjectType">UmbracoObjectType of the children to retrieve</param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
|
||||
internal IEnumerable<IUmbracoEntity> GetChildrenWithoutPropertyData(int parentId, UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
return GetChildrenInternal(parentId, umbracoObjectType, false);
|
||||
}
|
||||
|
||||
internal IEnumerable<IUmbracoEntity> GetChildrenInternal(int parentId, UmbracoObjectTypes umbracoObjectType, bool includePropertyData)
|
||||
{
|
||||
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);
|
||||
|
||||
var contents = repository.GetByQuery(query, objectTypeId);
|
||||
return contents;
|
||||
if (includePropertyData)
|
||||
return repository.GetByQuery(query, objectTypeId);
|
||||
|
||||
// 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).GetByQueryWithoutPropertyData(query, objectTypeId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -781,4 +802,4 @@ namespace Umbraco.Core.Services
|
||||
return node.NodeId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,7 +202,11 @@ namespace Umbraco.Web.Trees
|
||||
entityId = entity.Id;
|
||||
}
|
||||
|
||||
return Services.EntityService.GetChildren(entityId, UmbracoObjectType).ToList();
|
||||
// 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
|
||||
return ((EntityService)Services.EntityService).GetChildrenWithoutPropertyData(entityId, UmbracoObjectType).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user