diff --git a/src/Umbraco.Core/Models/UmbracoEntity.cs b/src/Umbraco.Core/Models/UmbracoEntity.cs
index b789698704..7783331952 100644
--- a/src/Umbraco.Core/Models/UmbracoEntity.cs
+++ b/src/Umbraco.Core/Models/UmbracoEntity.cs
@@ -225,42 +225,5 @@ namespace Umbraco.Core.Models
return clone;
}
- ///
- /// A struction that can be contained in the additional data of an UmbracoEntity representing
- /// a user defined property
- ///
- public class EntityProperty : IDeepCloneable
- {
- public string PropertyEditorAlias { get; set; }
- public object Value { get; set; }
- public object DeepClone()
- {
- //Memberwise clone on Entity will work since it doesn't have any deep elements
- // for any sub class this will work for standard properties as well that aren't complex object's themselves.
- var clone = MemberwiseClone();
- return clone;
- }
-
- protected bool Equals(EntityProperty other)
- {
- return PropertyEditorAlias.Equals(other.PropertyEditorAlias) && string.Equals(Value, other.Value);
- }
-
- public override bool Equals(object obj)
- {
- if (ReferenceEquals(null, obj)) return false;
- if (ReferenceEquals(this, obj)) return true;
- if (obj.GetType() != this.GetType()) return false;
- return Equals((EntityProperty) obj);
- }
-
- public override int GetHashCode()
- {
- unchecked
- {
- return (PropertyEditorAlias.GetHashCode() * 397) ^ (Value != null ? Value.GetHashCode() : 0);
- }
- }
- }
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
index 495c0109ad..7b10b19e1e 100644
--- a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
@@ -20,27 +20,22 @@ namespace Umbraco.Core.Persistence.Repositories
///
internal class EntityRepository : DisposableObjectSlim, IEntityRepository
{
- private readonly IDatabaseUnitOfWork _work;
-
public EntityRepository(IDatabaseUnitOfWork work)
{
- _work = work;
+ UnitOfWork = work;
}
///
/// Returns the Unit of Work added to the repository
///
- protected internal IDatabaseUnitOfWork UnitOfWork
- {
- get { return _work; }
- }
+ protected internal IDatabaseUnitOfWork UnitOfWork { get; }
///
/// Internal for testing purposes
///
internal Guid UnitKey
{
- get { return (Guid)_work.Key; }
+ get { return (Guid)UnitOfWork.Key; }
}
#region Query Methods
@@ -69,75 +64,8 @@ namespace Umbraco.Core.Persistence.Repositories
IEnumerable result;
- if (isMedia)
- {
- //Treat media differently for now, as an Entity it will be returned with ALL of it's properties in the AdditionalData bag!
- var pagedResult = _work.Database.Page(pageIndex + 1, pageSize, pagedSql);
-
- var ids = pagedResult.Items.Select(x => (int) x.id).InGroupsOf(2000);
- var entities = pagedResult.Items.Select(factory.BuildEntityFromDynamic).Cast().ToList();
-
- //Now we need to merge in the property data since we need paging and we can't do this the way that the big media query was working before
- foreach (var idGroup in ids)
- {
- var propSql = GetPropertySql(Constants.ObjectTypes.Media)
- .Where("contentNodeId IN (@ids)", new { ids = idGroup });
- propSql = (orderDirection == Direction.Descending) ? propSql.OrderByDescending("contentNodeId") : propSql.OrderBy("contentNodeId");
-
- //This does NOT fetch all data into memory in a list, this will read
- // over the records as a data reader, this is much better for performance and memory,
- // but it means that during the reading of this data set, nothing else can be read
- // from SQL server otherwise we'll get an exception.
- var allPropertyData = _work.Database.Query(propSql);
-
- //keep track of the current property data item being enumerated
- var propertyDataSetEnumerator = allPropertyData.GetEnumerator();
- var hasCurrent = false; // initially there is no enumerator.Current
-
- try
- {
- //This must be sorted by node id (which is done by SQL) because this is how we are sorting the query to lookup property types above,
- // which allows us to more efficiently iterate over the large data set of property values.
- foreach (var entity in entities)
- {
- // assemble the dtos for this def
- // use the available enumerator.Current if any else move to next
- while (hasCurrent || propertyDataSetEnumerator.MoveNext())
- {
- if (propertyDataSetEnumerator.Current.contentNodeId == entity.Id)
- {
- hasCurrent = false; // enumerator.Current is not available
-
- //the property data goes into the additional data
- entity.AdditionalData[propertyDataSetEnumerator.Current.propertyTypeAlias] = new UmbracoEntity.EntityProperty
- {
- PropertyEditorAlias = propertyDataSetEnumerator.Current.propertyEditorAlias,
- Value = StringExtensions.IsNullOrWhiteSpace(propertyDataSetEnumerator.Current.dataNtext)
- ? propertyDataSetEnumerator.Current.dataNvarchar
- : StringExtensions.ConvertToJsonIfPossible(propertyDataSetEnumerator.Current.dataNtext)
- };
- }
- else
- {
- hasCurrent = true; // enumerator.Current is available for another def
- break; // no more propertyDataDto for this def
- }
- }
- }
- }
- finally
- {
- propertyDataSetEnumerator.Dispose();
- }
- }
-
- result = entities;
- }
- else
- {
- var pagedResult = _work.Database.Page(pageIndex + 1, pageSize, pagedSql);
- result = pagedResult.Items.Select(factory.BuildEntityFromDynamic).Cast().ToList();
- }
+ var pagedResult = UnitOfWork.Database.Page(pageIndex + 1, pageSize, pagedSql);
+ result = pagedResult.Items.Select(factory.BuildEntityFromDynamic).Cast().ToList();
//The total items from the PetaPoco page query will be wrong due to the Outer join used on parent, depending on the search this will
//return duplicate results when the COUNT is used in conjuction with it, so we need to get the total on our own.
@@ -159,7 +87,7 @@ namespace Umbraco.Core.Persistence.Repositories
var translatorCount = new SqlTranslator(sqlCountClause, query);
var countSql = translatorCount.Translate();
- totalRecords = _work.Database.ExecuteScalar(countSql);
+ totalRecords = UnitOfWork.Database.ExecuteScalar(countSql);
return result;
}
@@ -167,7 +95,7 @@ namespace Umbraco.Core.Persistence.Repositories
public IUmbracoEntity GetByKey(Guid key)
{
var sql = GetBaseWhere(GetBase, false, false, key);
- var nodeDto = _work.Database.FirstOrDefault(sql);
+ var nodeDto = UnitOfWork.Database.FirstOrDefault(sql);
if (nodeDto == null)
return null;
@@ -187,7 +115,7 @@ namespace Umbraco.Core.Persistence.Repositories
var factory = new UmbracoEntityFactory();
//query = read forward data reader, do not load everything into mem
- var dtos = _work.Database.Query(sql);
+ var dtos = UnitOfWork.Database.Query(sql);
var collection = new EntityDefinitionCollection();
foreach (var dto in dtos)
{
@@ -202,7 +130,7 @@ namespace Umbraco.Core.Persistence.Repositories
public virtual IUmbracoEntity Get(int id)
{
var sql = GetBaseWhere(GetBase, false, false, id);
- var nodeDto = _work.Database.FirstOrDefault(sql);
+ var nodeDto = UnitOfWork.Database.FirstOrDefault(sql);
if (nodeDto == null)
return null;
@@ -222,7 +150,7 @@ namespace Umbraco.Core.Persistence.Repositories
var factory = new UmbracoEntityFactory();
//query = read forward data reader, do not load everything into mem
- var dtos = _work.Database.Query(sql);
+ var dtos = UnitOfWork.Database.Query(sql);
var collection = new EntityDefinitionCollection();
foreach (var dto in dtos)
{
@@ -256,7 +184,7 @@ namespace Umbraco.Core.Persistence.Repositories
var factory = new UmbracoEntityFactory();
//query = read forward data reader, do not load everything into mem
- var dtos = _work.Database.Query(sql);
+ var dtos = UnitOfWork.Database.Query(sql);
var collection = new EntityDefinitionCollection();
foreach (var dto in dtos)
{
@@ -283,7 +211,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
var sql = new Sql("SELECT id, path FROM umbracoNode WHERE umbracoNode.nodeObjectType=@type", new { type = objectTypeId });
if (filter != null) filter(sql);
- return _work.Database.Fetch(sql);
+ return UnitOfWork.Database.Fetch(sql);
}
public virtual IEnumerable GetByQuery(IQuery query)
@@ -292,7 +220,7 @@ namespace Umbraco.Core.Persistence.Repositories
var translator = new SqlTranslator(sqlClause, query);
var sql = translator.Translate().Append(GetGroupBy(false, false));
- var dtos = _work.Database.Fetch(sql);
+ var dtos = UnitOfWork.Database.Fetch(sql);
var factory = new UmbracoEntityFactory();
var list = dtos.Select(factory.BuildEntityFromDynamic).Cast().ToList();
@@ -306,10 +234,6 @@ namespace Umbraco.Core.Persistence.Repositories
///
///
///
- ///
- /// 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.
- ///
public virtual IEnumerable GetByQuery(IQuery query, Guid objectTypeId)
{
var isContent = objectTypeId == Constants.ObjectTypes.DocumentGuid || objectTypeId == Constants.ObjectTypes.DocumentBlueprintGuid;
@@ -323,27 +247,7 @@ namespace Umbraco.Core.Persistence.Repositories
return GetByQueryInternal(entitySql, isContent, isMedia);
}
- ///
- /// 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.
- ///
- internal IEnumerable GetMediaByQueryWithoutPropertyData(IQuery query)
- {
- var sqlClause = GetBaseWhere(GetBase, false, true, null, UmbracoObjectTypes.Media.GetGuid());
-
- var translator = new SqlTranslator(sqlClause, query);
- var entitySql = translator.Translate();
-
- return GetByQueryInternal(entitySql, false, true);
- }
-
- internal IEnumerable GetByQueryInternal(Sql entitySql, bool isContent, bool isMedia)
+ private IEnumerable GetByQueryInternal(Sql entitySql, bool isContent, bool isMedia)
{
var factory = new UmbracoEntityFactory();
@@ -351,7 +255,7 @@ namespace Umbraco.Core.Persistence.Repositories
var finalSql = entitySql.Append(GetGroupBy(isContent, isMedia));
//query = read forward data reader, do not load everything into mem
- var dtos = _work.Database.Query(finalSql);
+ var dtos = UnitOfWork.Database.Query(finalSql);
var collection = new EntityDefinitionCollection();
foreach (var dto in dtos)
{
@@ -392,22 +296,6 @@ namespace Umbraco.Core.Persistence.Repositories
return entitySql.Append(GetGroupBy(isContent, true, false));
}
- private Sql GetPropertySql(string nodeObjectType)
- {
- var sql = new Sql()
- .Select("contentNodeId, versionId, dataNvarchar, dataNtext, propertyEditorAlias, alias as propertyTypeAlias")
- .From()
- .InnerJoin()
- .On(dto => dto.NodeId, dto => dto.NodeId)
- .InnerJoin()
- .On(dto => dto.Id, dto => dto.PropertyTypeId)
- .InnerJoin()
- .On(dto => dto.DataTypeId, dto => dto.DataTypeId)
- .Where("umbracoNode.nodeObjectType = @nodeObjectType", new { nodeObjectType = nodeObjectType });
-
- return sql;
- }
-
protected virtual Sql GetBase(bool isContent, bool isMedia, Action customFilter)
{
return GetBase(isContent, isMedia, customFilter, false);
@@ -638,13 +526,13 @@ namespace Umbraco.Core.Persistence.Repositories
public bool Exists(Guid key)
{
var sql = new Sql().Select("COUNT(*)").From("umbracoNode").Where("uniqueID=@uniqueID", new {uniqueID = key});
- return _work.Database.ExecuteScalar(sql) > 0;
+ return UnitOfWork.Database.ExecuteScalar(sql) > 0;
}
public bool Exists(int id)
{
var sql = new Sql().Select("COUNT(*)").From("umbracoNode").Where("id=@id", new { id = id });
- return _work.Database.ExecuteScalar(sql) > 0;
+ return UnitOfWork.Database.ExecuteScalar(sql) > 0;
}
#region private classes
diff --git a/src/Umbraco.Core/Services/EntityService.cs b/src/Umbraco.Core/Services/EntityService.cs
index 906ece1081..f4b1b71732 100644
--- a/src/Umbraco.Core/Services/EntityService.cs
+++ b/src/Umbraco.Core/Services/EntityService.cs
@@ -234,27 +234,6 @@ namespace Umbraco.Core.Services
}
}
- ///
- /// Gets a collection of children by the parent's Id and UmbracoObjectType without adding property data
- ///
- /// Id of the parent to retrieve children for
- /// An enumerable list of objects
- internal IEnumerable GetMediaChildrenWithoutPropertyData(int parentId)
- {
- var objectTypeId = UmbracoObjectTypes.Media.GetGuid();
- using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
- {
- var repository = RepositoryFactory.CreateEntityRepository(uow);
- var query = Query.Builder.Where(x => x.ParentId == parentId);
-
- // 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);
- }
- }
-
///
/// Returns a paged collection of children
///
diff --git a/src/Umbraco.Tests/Models/UmbracoEntityTests.cs b/src/Umbraco.Tests/Models/UmbracoEntityTests.cs
index 7186474999..1ab6bbea31 100644
--- a/src/Umbraco.Tests/Models/UmbracoEntityTests.cs
+++ b/src/Umbraco.Tests/Models/UmbracoEntityTests.cs
@@ -177,18 +177,7 @@ namespace Umbraco.Tests.Models
};
item.AdditionalData.Add("test1", 3);
item.AdditionalData.Add("test2", "valuie");
-
- item.AdditionalData.Add("test3", new UmbracoEntity.EntityProperty()
- {
- Value = "test",
- PropertyEditorAlias = "TestPropertyEditor"
- });
- item.AdditionalData.Add("test4", new UmbracoEntity.EntityProperty()
- {
- Value = "test2",
- PropertyEditorAlias = "TestPropertyEditor2"
- });
-
+
var clone = (UmbracoEntity)item.DeepClone();
Assert.AreNotSame(clone, item);
@@ -250,20 +239,10 @@ namespace Umbraco.Tests.Models
};
item.AdditionalData.Add("test1", 3);
item.AdditionalData.Add("test2", "valuie");
- item.AdditionalData.Add("test3", new UmbracoEntity.EntityProperty()
- {
- Value = "test",
- PropertyEditorAlias = "TestPropertyEditor"
- });
- item.AdditionalData.Add("test4", new UmbracoEntity.EntityProperty()
- {
- Value = "test2",
- PropertyEditorAlias = "TestPropertyEditor2"
- });
-
+
var result = ss.ToStream(item);
var json = result.ResultStream.ToJsonString();
Debug.Print(json);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs
index 54adb24b74..e7fb0b8d84 100644
--- a/src/Umbraco.Web/Trees/ContentTreeController.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeController.cs
@@ -207,9 +207,6 @@ namespace Umbraco.Web.Trees
return HasPathAccess(entity, queryStrings);
}
- internal override IEnumerable GetChildrenFromEntityService(int entityId)
- => Services.EntityService.GetChildren(entityId, UmbracoObjectType).ToList();
-
///
/// Returns a collection of all menu items that can be on a content node
///
diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
index 2624c89b56..4e4086a3c6 100644
--- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
@@ -205,12 +205,8 @@ namespace Umbraco.Web.Trees
return GetChildrenFromEntityService(entityId);
}
- ///
- /// Abstract method to fetch the entities from the entity service
- ///
- ///
- ///
- internal abstract IEnumerable GetChildrenFromEntityService(int entityId);
+ private IEnumerable GetChildrenFromEntityService(int entityId)
+ => Services.EntityService.GetChildren(entityId, UmbracoObjectType).ToList();
///
/// Returns true or false if the current user has access to the node based on the user's allowed start node (path) access
diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs
index f2f59b6bd7..50336dbc10 100644
--- a/src/Umbraco.Web/Trees/MediaTreeController.cs
+++ b/src/Umbraco.Web/Trees/MediaTreeController.cs
@@ -177,12 +177,6 @@ namespace Umbraco.Web.Trees
{
return _treeSearcher.ExamineSearch(Umbraco, query, UmbracoEntityTypes.Media, pageSize, pageIndex, out totalFound, searchFrom);
}
-
- internal override IEnumerable 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();
+
}
}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index d4fd27c323..32eaae1077 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -1812,7 +1812,6 @@
-
diff --git a/src/Umbraco.Web/WebServices/FolderBrowserService.cs b/src/Umbraco.Web/WebServices/FolderBrowserService.cs
deleted file mode 100644
index 15a6c10880..0000000000
--- a/src/Umbraco.Web/WebServices/FolderBrowserService.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Web.Script.Serialization;
-using Umbraco.Core;
-using Umbraco.Core.IO;
-using Umbraco.Core.Models;
-using Umbraco.Web.Media.ThumbnailProviders;
-using umbraco.BusinessLogic;
-using umbraco.cms.businesslogic.Tags;
-using Umbraco.Web.BaseRest;
-using Tag = umbraco.cms.businesslogic.Tags.Tag;
-
-namespace Umbraco.Web.WebServices
-{
- //TODO: Can we convert this to MVC please instead of /base?
- [Obsolete("Thumbnails are generated by ImageProcessor, use that instead")]
- [RestExtension("FolderBrowserService")]
- public class FolderBrowserService
- {
- [RestExtensionMethod(ReturnXml = false)]
- public static string GetChildren(int parentId)
- {
- var currentUser = GetCurrentUser();
- AuthorizeAccess(parentId, currentUser);
-
- // Get children and filter
- var data = new List