Gets entity repository to be able to return a mix of object types
This commit is contained in:
@@ -108,6 +108,9 @@ namespace Umbraco.Core.Models
|
||||
[IgnoreDataMember]
|
||||
public int VersionId { get; set; }
|
||||
|
||||
[DataMember]
|
||||
public Guid NodeObjectType { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Integer Id of the default ContentType
|
||||
/// </summary>
|
||||
|
||||
@@ -113,6 +113,9 @@ namespace Umbraco.Core.Models
|
||||
OnPropertyChanged(nameof(PropertyTypes));
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public Guid NodeObjectType { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Alias of the ContentType
|
||||
/// </summary>
|
||||
|
||||
@@ -65,6 +65,9 @@ namespace Umbraco.Core.Models
|
||||
[DataMember]
|
||||
public string EditorAlias => _editor.Alias;
|
||||
|
||||
[DataMember]
|
||||
public Guid NodeObjectType { get; internal set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[DataMember]
|
||||
public ValueStorageType DatabaseType
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
/// Sets the parent entity.
|
||||
/// </summary>
|
||||
/// <remarks>Use this method to set the parent entity when the parent entity is known, but has not
|
||||
/// been persistent and does not yet have an identity. The parent identifier will we retrieved
|
||||
/// been persistent and does not yet have an identity. The parent identifier will be retrieved
|
||||
/// from the parent entity when needed. If the parent entity still does not have an entity by that
|
||||
/// time, an exception will be thrown by <see cref="ParentId"/> getter.</remarks>
|
||||
void SetParent(ITreeEntity parent);
|
||||
@@ -53,4 +53,4 @@
|
||||
/// </remarks>
|
||||
bool Trashed { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Models.Entities
|
||||
{
|
||||
@@ -11,5 +12,7 @@ namespace Umbraco.Core.Models.Entities
|
||||
/// <para>An IUmbracoEntity can participate in notifications.</para>
|
||||
/// </remarks>
|
||||
public interface IUmbracoEntity : ITreeEntity, IRememberBeingDirty
|
||||
{ }
|
||||
{
|
||||
Guid NodeObjectType { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
public Guid ContainerObjectType => ObjectTypeMap[_containedObjectType];
|
||||
|
||||
Guid IUmbracoEntity.NodeObjectType => ContainerObjectType;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the container object type corresponding to a contained object type.
|
||||
/// </summary>
|
||||
|
||||
@@ -44,11 +44,14 @@ namespace Umbraco.Core.Models
|
||||
Name = contentType.Name;
|
||||
AllowedAsRoot = contentType.AllowedAsRoot;
|
||||
IsElement = contentType.IsElement;
|
||||
NodeObjectType = contentType.NodeObjectType;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Alias { get; }
|
||||
|
||||
public Guid NodeObjectType { get; }
|
||||
|
||||
public int Id { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
content.VersionId = contentVersionDto.Id;
|
||||
|
||||
content.Name = contentVersionDto.Text;
|
||||
|
||||
content.NodeObjectType = nodeDto.NodeObjectType ?? Guid.Empty;
|
||||
content.Path = nodeDto.Path;
|
||||
content.Level = nodeDto.Level;
|
||||
content.ParentId = nodeDto.ParentId;
|
||||
|
||||
@@ -107,6 +107,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
entity.Id = dto.NodeDto.NodeId;
|
||||
entity.Key = dto.NodeDto.UniqueId;
|
||||
entity.NodeObjectType = dto.NodeDto.NodeObjectType ?? Guid.Empty;
|
||||
entity.Alias = dto.Alias;
|
||||
entity.Name = dto.NodeDto.Text;
|
||||
entity.Icon = dto.Icon;
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
dataType.DisableChangeTracking();
|
||||
|
||||
dataType.CreateDate = dto.NodeDto.CreateDate;
|
||||
dataType.NodeObjectType = dto.NodeDto.NodeObjectType ?? Guid.Empty;
|
||||
dataType.DatabaseType = dto.DbType.EnumParse<ValueStorageType>(true);
|
||||
dataType.Id = dto.NodeId;
|
||||
dataType.Key = dto.NodeDto.UniqueId;
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.Trashed), nameof(NodeDto.Trashed));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.Key), nameof(NodeDto.UniqueId));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.CreatorId), nameof(NodeDto.UserId));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.NodeObjectType), nameof(NodeDto.NodeObjectType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,22 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
IEntitySlim Get(int id, Guid objectTypeId);
|
||||
IEntitySlim Get(Guid key, Guid objectTypeId);
|
||||
|
||||
IEnumerable<IEntitySlim> GetAll(Guid objectType, params int[] ids);
|
||||
IEnumerable<IEntitySlim> GetAll(Guid objectType, params int[] ids);
|
||||
IEnumerable<IEntitySlim> GetAll(Guid objectType, params Guid[] keys);
|
||||
|
||||
/// <summary>
|
||||
/// Gets entities for a query
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IEntitySlim> GetByQuery(IQuery<IUmbracoEntity> query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets entities for a query and a specific object type allowing the query to be slightly more optimized
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="objectType"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IEntitySlim> GetByQuery(IQuery<IUmbracoEntity> query, Guid objectType);
|
||||
|
||||
UmbracoObjectTypes GetObjectType(int id);
|
||||
@@ -30,7 +42,36 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
bool Exists(int id);
|
||||
bool Exists(Guid key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged entities for a query and a subset of object types
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="totalRecords"></param>
|
||||
/// <param name="filter"></param>
|
||||
/// <param name="ordering"></param>
|
||||
/// <returns>
|
||||
/// A collection of mixed entity types which would be of type <see cref="IEntitySlim"/>, <see cref="IDocumentEntitySlim"/>, <see cref="IMediaEntitySlim"/>,
|
||||
/// <see cref="IMemberEntitySlim"/>
|
||||
/// </returns>
|
||||
IEnumerable<IEntitySlim> GetPagedResultsByQuery(IQuery<IUmbracoEntity> query, Guid[] objectTypes, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IUmbracoEntity> filter, Ordering ordering);
|
||||
|
||||
/// <summary>
|
||||
/// Gets paged entities for a query and a specific object type
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="objectType"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="totalRecords"></param>
|
||||
/// <param name="filter"></param>
|
||||
/// <param name="ordering"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IEntitySlim> GetPagedResultsByQuery(IQuery<IUmbracoEntity> query, Guid objectType, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IUmbracoEntity> filter, Ordering ordering);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,26 +36,70 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
#region Repository
|
||||
|
||||
// get a page of entities
|
||||
//public IEnumerable<IEntitySlim> GetPagedResults(IDictionary<Guid, IEnumerable<int>> typesAndIds, long pageIndex, int pageSize, out long totalRecords, Ordering ordering)
|
||||
//{
|
||||
// var isContent = typesAndIds.Keys.Any(objectType => objectType == Constants.ObjectTypes.Document || objectType == Constants.ObjectTypes.DocumentBlueprint);
|
||||
// var isMedia = typesAndIds.Keys.Any(objectType => objectType == Constants.ObjectTypes.Media);
|
||||
// var isMember = typesAndIds.Keys.Any(objectType => objectType == Constants.ObjectTypes.Member);
|
||||
|
||||
// var sql = GetBase(isContent, isMedia, isMember, null, false)
|
||||
// .WhereIn<NodeDto>(x => x.NodeObjectType, typesAndIds.Keys);
|
||||
|
||||
// ordering = ordering ?? Ordering.ByDefault();
|
||||
|
||||
// sql = AddGroupBy(isContent, isMedia, isMember, sql, ordering.IsEmpty);
|
||||
|
||||
// if (!ordering.IsEmpty)
|
||||
// {
|
||||
// // apply ordering
|
||||
// ApplyOrdering(ref sql, ordering);
|
||||
// }
|
||||
|
||||
// // TODO: we should be able to do sql = sql.OrderBy(x => Alias(x.NodeId, "NodeId")); but we can't because the OrderBy extension don't support Alias currently
|
||||
// //no matter what we always must have node id ordered at the end
|
||||
// sql = ordering.Direction == Direction.Ascending ? sql.OrderBy("NodeId") : sql.OrderByDescending("NodeId");
|
||||
|
||||
// // for content we must query for ContentEntityDto entities to produce the correct culture variant entity names
|
||||
// var pageIndexToFetch = pageIndex + 1;
|
||||
// IEnumerable<BaseDto> dtos;
|
||||
// var page = Database.Page<GenericContentEntityDto>(pageIndexToFetch, pageSize, sql);
|
||||
// dtos = page.Items;
|
||||
// totalRecords = page.TotalItems;
|
||||
|
||||
// var entities = dtos.Select(BuildEntity).ToArray();
|
||||
|
||||
// BuildVariants(entities.OfType<DocumentEntitySlim>());
|
||||
|
||||
// return entities;
|
||||
//}
|
||||
|
||||
public IEnumerable<IEntitySlim> GetPagedResultsByQuery(IQuery<IUmbracoEntity> query, Guid objectType, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IUmbracoEntity> filter, Ordering ordering)
|
||||
{
|
||||
var isContent = objectType == Constants.ObjectTypes.Document || objectType == Constants.ObjectTypes.DocumentBlueprint;
|
||||
var isMedia = objectType == Constants.ObjectTypes.Media;
|
||||
var isMember = objectType == Constants.ObjectTypes.Member;
|
||||
query = query.Where(x => x.NodeObjectType == objectType);
|
||||
return GetPagedResultsByQuery(query, new[] { objectType }, pageIndex, pageSize, out totalRecords, filter, ordering);
|
||||
}
|
||||
|
||||
// get a page of entities
|
||||
public IEnumerable<IEntitySlim> GetPagedResultsByQuery(IQuery<IUmbracoEntity> query, Guid[] objectTypes, long pageIndex, int pageSize, out long totalRecords,
|
||||
IQuery<IUmbracoEntity> filter, Ordering ordering)
|
||||
{
|
||||
var isContent = objectTypes.Any(objectType => objectType == Constants.ObjectTypes.Document || objectType == Constants.ObjectTypes.DocumentBlueprint);
|
||||
var isMedia = objectTypes.Any(objectType => objectType == Constants.ObjectTypes.Media);
|
||||
var isMember = objectTypes.Any(objectType => objectType == Constants.ObjectTypes.Member);
|
||||
|
||||
var sql = GetBaseWhere(isContent, isMedia, isMember, false, x =>
|
||||
{
|
||||
if (filter == null) return;
|
||||
foreach (var filterClause in filter.GetWhereClauses())
|
||||
x.Where(filterClause.Item1, filterClause.Item2);
|
||||
}, objectType);
|
||||
}, objectTypes);
|
||||
|
||||
ordering = ordering ?? Ordering.ByDefault();
|
||||
|
||||
var translator = new SqlTranslator<IUmbracoEntity>(sql, query);
|
||||
sql = translator.Translate();
|
||||
sql = AddGroupBy(isContent, isMedia, isMember, sql, ordering.IsEmpty);
|
||||
sql = AddGroupBy(true, true, true, sql, ordering.IsEmpty);
|
||||
|
||||
if (!ordering.IsEmpty)
|
||||
{
|
||||
@@ -70,35 +114,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// for content we must query for ContentEntityDto entities to produce the correct culture variant entity names
|
||||
var pageIndexToFetch = pageIndex + 1;
|
||||
IEnumerable<BaseDto> dtos;
|
||||
if(isContent)
|
||||
{
|
||||
var page = Database.Page<ContentEntityDto>(pageIndexToFetch, pageSize, sql);
|
||||
dtos = page.Items;
|
||||
totalRecords = page.TotalItems;
|
||||
}
|
||||
else if (isMedia)
|
||||
{
|
||||
var page = Database.Page<MediaEntityDto>(pageIndexToFetch, pageSize, sql);
|
||||
dtos = page.Items;
|
||||
totalRecords = page.TotalItems;
|
||||
}
|
||||
else if (isMember)
|
||||
{
|
||||
var page = Database.Page<MemberEntityDto>(pageIndexToFetch, pageSize, sql);
|
||||
dtos = page.Items;
|
||||
totalRecords = page.TotalItems;
|
||||
}
|
||||
else
|
||||
{
|
||||
var page = Database.Page<BaseDto>(pageIndexToFetch, pageSize, sql);
|
||||
dtos = page.Items;
|
||||
totalRecords = page.TotalItems;
|
||||
}
|
||||
var page = Database.Page<GenericContentEntityDto>(pageIndexToFetch, pageSize, sql);
|
||||
dtos = page.Items;
|
||||
totalRecords = page.TotalItems;
|
||||
|
||||
var entities = dtos.Select(x => BuildEntity(isContent, isMedia, isMember, x)).ToArray();
|
||||
var entities = dtos.Select(BuildEntity).ToArray();
|
||||
|
||||
if (isContent)
|
||||
BuildVariants(entities.Cast<DocumentEntitySlim>());
|
||||
BuildVariants(entities.OfType<DocumentEntitySlim>());
|
||||
|
||||
return entities;
|
||||
}
|
||||
@@ -107,7 +129,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
var sql = GetBaseWhere(false, false, false, false, key);
|
||||
var dto = Database.FirstOrDefault<BaseDto>(sql);
|
||||
return dto == null ? null : BuildEntity(false, false, false, dto);
|
||||
return dto == null ? null : BuildEntity(dto);
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +138,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
//isContent is going to return a 1:M result now with the variants so we need to do different things
|
||||
if (isContent)
|
||||
{
|
||||
var cdtos = Database.Fetch<ContentEntityDto>(sql);
|
||||
var cdtos = Database.Fetch<DocumentEntityDto>(sql);
|
||||
|
||||
return cdtos.Count == 0 ? null : BuildVariants(BuildDocumentEntity(cdtos[0]));
|
||||
}
|
||||
@@ -127,7 +149,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
if (dto == null) return null;
|
||||
|
||||
var entity = BuildEntity(false, isMedia, isMember, dto);
|
||||
var entity = BuildEntity(dto);
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -146,7 +168,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
var sql = GetBaseWhere(false, false, false, false, id);
|
||||
var dto = Database.FirstOrDefault<BaseDto>(sql);
|
||||
return dto == null ? null : BuildEntity(false, false, false, dto);
|
||||
return dto == null ? null : BuildEntity(dto);
|
||||
}
|
||||
|
||||
public IEntitySlim Get(int id, Guid objectTypeId)
|
||||
@@ -178,7 +200,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
//isContent is going to return a 1:M result now with the variants so we need to do different things
|
||||
if (isContent)
|
||||
{
|
||||
var cdtos = Database.Fetch<ContentEntityDto>(sql);
|
||||
var cdtos = Database.Fetch<DocumentEntityDto>(sql);
|
||||
|
||||
return cdtos.Count == 0
|
||||
? Enumerable.Empty<IEntitySlim>()
|
||||
@@ -189,7 +211,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
? (IEnumerable<BaseDto>)Database.Fetch<MediaEntityDto>(sql)
|
||||
: Database.Fetch<BaseDto>(sql);
|
||||
|
||||
var entities = dtos.Select(x => BuildEntity(false, isMedia, isMember, x)).ToArray();
|
||||
var entities = dtos.Select(BuildEntity).ToArray();
|
||||
|
||||
return entities;
|
||||
}
|
||||
@@ -233,7 +255,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
var sql = translator.Translate();
|
||||
sql = AddGroupBy(false, false, false, sql, true);
|
||||
var dtos = Database.Fetch<BaseDto>(sql);
|
||||
return dtos.Select(x => BuildEntity(false, false, false, x)).ToList();
|
||||
return dtos.Select(BuildEntity).ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<IEntitySlim> GetByQuery(IQuery<IUmbracoEntity> query, Guid objectType)
|
||||
@@ -242,7 +264,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
var isMedia = objectType == Constants.ObjectTypes.Media;
|
||||
var isMember = objectType == Constants.ObjectTypes.Member;
|
||||
|
||||
var sql = GetBaseWhere(isContent, isMedia, isMember, false, null, objectType);
|
||||
var sql = GetBaseWhere(isContent, isMedia, isMember, false, null, new[] { objectType });
|
||||
|
||||
var translator = new SqlTranslator<IUmbracoEntity>(sql, query);
|
||||
sql = translator.Translate();
|
||||
@@ -356,14 +378,14 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
// gets the full sql for a given object type, with a given filter
|
||||
protected Sql<ISqlContext> GetFullSqlForEntityType(bool isContent, bool isMedia, bool isMember, Guid objectType, Action<Sql<ISqlContext>> filter)
|
||||
{
|
||||
var sql = GetBaseWhere(isContent, isMedia, isMember, false, filter, objectType);
|
||||
var sql = GetBaseWhere(isContent, isMedia, isMember, false, filter, new[] { objectType });
|
||||
return AddGroupBy(isContent, isMedia, isMember, sql, true);
|
||||
}
|
||||
|
||||
// gets the base SELECT + FROM [+ filter] sql
|
||||
// always from the 'current' content version
|
||||
protected Sql<ISqlContext> GetBase(bool isContent, bool isMedia, bool isMember, Action<Sql<ISqlContext>> filter, bool isCount = false)
|
||||
{
|
||||
{
|
||||
var sql = Sql();
|
||||
|
||||
if (isCount)
|
||||
@@ -401,15 +423,15 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (isContent || isMedia || isMember)
|
||||
{
|
||||
sql
|
||||
.InnerJoin<ContentVersionDto>().On<NodeDto, ContentVersionDto>((left, right) => left.NodeId == right.NodeId && right.Current)
|
||||
.InnerJoin<ContentDto>().On<NodeDto, ContentDto>((left, right) => left.NodeId == right.NodeId)
|
||||
.InnerJoin<ContentTypeDto>().On<ContentDto, ContentTypeDto>((left, right) => left.ContentTypeId == right.NodeId);
|
||||
.LeftJoin<ContentVersionDto>().On<NodeDto, ContentVersionDto>((left, right) => left.NodeId == right.NodeId && right.Current)
|
||||
.LeftJoin<ContentDto>().On<NodeDto, ContentDto>((left, right) => left.NodeId == right.NodeId)
|
||||
.LeftJoin<ContentTypeDto>().On<ContentDto, ContentTypeDto>((left, right) => left.ContentTypeId == right.NodeId);
|
||||
}
|
||||
|
||||
if (isContent)
|
||||
{
|
||||
sql
|
||||
.InnerJoin<DocumentDto>().On<NodeDto, DocumentDto>((left, right) => left.NodeId == right.NodeId);
|
||||
.LeftJoin<DocumentDto>().On<NodeDto, DocumentDto>((left, right) => left.NodeId == right.NodeId);
|
||||
}
|
||||
|
||||
if (isMedia)
|
||||
@@ -433,10 +455,10 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
// gets the base SELECT + FROM [+ filter] + WHERE sql
|
||||
// for a given object type, with a given filter
|
||||
protected Sql<ISqlContext> GetBaseWhere(bool isContent, bool isMedia, bool isMember, bool isCount, Action<Sql<ISqlContext>> filter, Guid objectType)
|
||||
protected Sql<ISqlContext> GetBaseWhere(bool isContent, bool isMedia, bool isMember, bool isCount, Action<Sql<ISqlContext>> filter, Guid[] objectTypes)
|
||||
{
|
||||
return GetBase(isContent, isMedia, isMember, filter, isCount)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == objectType);
|
||||
.WhereIn<NodeDto>(x => x.NodeObjectType, objectTypes);
|
||||
}
|
||||
|
||||
// gets the base SELECT + FROM + WHERE sql
|
||||
@@ -510,8 +532,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
if (sql == null) throw new ArgumentNullException(nameof(sql));
|
||||
if (ordering == null) throw new ArgumentNullException(nameof(ordering));
|
||||
|
||||
// TODO: although this works for name, it probably doesn't work for others without an alias of some sort
|
||||
var orderBy = ordering.OrderBy;
|
||||
// TODO: although the default ordering string works for name, it wont work for others without a table or an alias of some sort
|
||||
// As more things are attempted to be sorted we'll prob have to add more expressions here
|
||||
var orderBy = ordering.OrderBy.ToUpperInvariant() switch
|
||||
{
|
||||
"PATH" => SqlSyntax.GetQuotedColumn(NodeDto.TableName, "path"),
|
||||
_ => ordering.OrderBy
|
||||
};
|
||||
|
||||
if (ordering.Direction == Direction.Ascending)
|
||||
sql.OrderBy(orderBy);
|
||||
@@ -524,9 +551,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
#region Classes
|
||||
|
||||
/// <summary>
|
||||
/// The DTO used to fetch results for a content item with its variation info
|
||||
/// The DTO used to fetch results for a generic content item which could be either a document, media or a member
|
||||
/// </summary>
|
||||
private class ContentEntityDto : BaseDto
|
||||
private class GenericContentEntityDto : DocumentEntityDto
|
||||
{
|
||||
public string MediaPath { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The DTO used to fetch results for a document item with its variation info
|
||||
/// </summary>
|
||||
private class DocumentEntityDto : BaseDto
|
||||
{
|
||||
public ContentVariation Variations { get; set; }
|
||||
|
||||
@@ -534,11 +569,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
public bool Edited { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The DTO used to fetch results for a media item with its media path info
|
||||
/// </summary>
|
||||
private class MediaEntityDto : BaseDto
|
||||
{
|
||||
public string MediaPath { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The DTO used to fetch results for a member item
|
||||
/// </summary>
|
||||
private class MemberEntityDto : BaseDto
|
||||
{
|
||||
}
|
||||
@@ -589,13 +630,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
#region Factory
|
||||
|
||||
private EntitySlim BuildEntity(bool isContent, bool isMedia, bool isMember, BaseDto dto)
|
||||
private EntitySlim BuildEntity(BaseDto dto)
|
||||
{
|
||||
if (isContent)
|
||||
if (dto.NodeObjectType == Constants.ObjectTypes.Document)
|
||||
return BuildDocumentEntity(dto);
|
||||
if (isMedia)
|
||||
if (dto.NodeObjectType == Constants.ObjectTypes.Media)
|
||||
return BuildMediaEntity(dto);
|
||||
if (isMember)
|
||||
if (dto.NodeObjectType == Constants.ObjectTypes.Member)
|
||||
return BuildMemberEntity(dto);
|
||||
|
||||
// EntitySlim does not track changes
|
||||
@@ -650,7 +691,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
var entity = new DocumentEntitySlim();
|
||||
BuildContentEntity(entity, dto);
|
||||
|
||||
if (dto is ContentEntityDto contentDto)
|
||||
if (dto is DocumentEntityDto contentDto)
|
||||
{
|
||||
// fill in the invariant info
|
||||
entity.Edited = contentDto.Edited;
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Repositories.Implement;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.TestHelpers.Entities;
|
||||
using Umbraco.Tests.Testing;
|
||||
|
||||
namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
[TestFixture]
|
||||
[UmbracoTest(Mapper = true, Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class EntityRepositoryTest : TestWithDatabaseBase
|
||||
{
|
||||
|
||||
private EntityRepository CreateRepository(IScopeAccessor scopeAccessor)
|
||||
{
|
||||
var entityRepository = new EntityRepository(scopeAccessor);
|
||||
return entityRepository;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Paged_Mixed_Entities_By_Ids()
|
||||
{
|
||||
//Create content
|
||||
|
||||
var createdContent = new List<IContent>();
|
||||
var contentType = MockedContentTypes.CreateBasicContentType("blah");
|
||||
ServiceContext.ContentTypeService.Save(contentType);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var c1 = MockedContent.CreateBasicContent(contentType);
|
||||
ServiceContext.ContentService.Save(c1);
|
||||
createdContent.Add(c1);
|
||||
}
|
||||
|
||||
//Create media
|
||||
|
||||
var createdMedia = new List<IMedia>();
|
||||
var imageType = MockedContentTypes.CreateImageMediaType("myImage");
|
||||
ServiceContext.MediaTypeService.Save(imageType);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var c1 = MockedMedia.CreateMediaImage(imageType, -1);
|
||||
ServiceContext.MediaService.Save(c1);
|
||||
createdMedia.Add(c1);
|
||||
}
|
||||
|
||||
// Create members
|
||||
var memberType = MockedContentTypes.CreateSimpleMemberType("simple");
|
||||
ServiceContext.MemberTypeService.Save(memberType);
|
||||
var createdMembers = MockedMember.CreateSimpleMember(memberType, 10).ToList();
|
||||
ServiceContext.MemberService.Save(createdMembers);
|
||||
|
||||
var provider = TestObjects.GetScopeProvider(Logger);
|
||||
using (var scope = provider.CreateScope())
|
||||
{
|
||||
var repo = CreateRepository((IScopeAccessor)provider);
|
||||
|
||||
var ids = createdContent.Select(x => x.Id).Concat(createdMedia.Select(x => x.Id)).Concat(createdMembers.Select(x => x.Id));
|
||||
|
||||
var objectTypes = new[] { Constants.ObjectTypes.Document, Constants.ObjectTypes.Media, Constants.ObjectTypes.Member };
|
||||
|
||||
var query = SqlContext.Query<IUmbracoEntity>()
|
||||
.WhereIn(e => e.Id, ids);
|
||||
|
||||
var entities = repo.GetPagedResultsByQuery(query, objectTypes, 0, 20, out var totalRecords, null, null).ToList();
|
||||
|
||||
Assert.AreEqual(20, entities.Count);
|
||||
Assert.AreEqual(30, totalRecords);
|
||||
|
||||
//add the next page
|
||||
entities.AddRange(repo.GetPagedResultsByQuery(query, objectTypes, 1, 20, out totalRecords, null, null));
|
||||
|
||||
Assert.AreEqual(30, entities.Count);
|
||||
Assert.AreEqual(30, totalRecords);
|
||||
|
||||
var contentEntities = entities.OfType<IDocumentEntitySlim>().ToList();
|
||||
var mediaEntities = entities.OfType<IMediaEntitySlim>().ToList();
|
||||
var memberEntities = entities.OfType<IMemberEntitySlim>().ToList();
|
||||
|
||||
Assert.AreEqual(10, contentEntities.Count);
|
||||
Assert.AreEqual(10, mediaEntities.Count);
|
||||
Assert.AreEqual(10, memberEntities.Count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -140,6 +140,7 @@
|
||||
<Compile Include="Models\VariationTests.cs" />
|
||||
<Compile Include="Persistence\Mappers\MapperTestBase.cs" />
|
||||
<Compile Include="Persistence\Repositories\DocumentRepositoryTest.cs" />
|
||||
<Compile Include="Persistence\Repositories\EntityRepositoryTest.cs" />
|
||||
<Compile Include="PublishedContent\NuCacheChildrenTests.cs" />
|
||||
<Compile Include="PublishedContent\PublishedContentLanguageVariantTests.cs" />
|
||||
<Compile Include="PublishedContent\PublishedContentSnapshotTestBase.cs" />
|
||||
|
||||
@@ -662,6 +662,9 @@ namespace Umbraco.Web.Editors
|
||||
if (pageSize <= 0)
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
|
||||
// re-normalize since NULL can be passed in
|
||||
filter = filter ?? string.Empty;
|
||||
|
||||
var objectType = ConvertToObjectType(type);
|
||||
if (objectType.HasValue)
|
||||
{
|
||||
|
||||
@@ -226,11 +226,11 @@ namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
switch (entity)
|
||||
{
|
||||
case ContentEntitySlim contentEntity:
|
||||
// NOTE: this case covers both content and media entities
|
||||
return contentEntity.ContentTypeIcon;
|
||||
case MemberEntitySlim memberEntity:
|
||||
case IMemberEntitySlim memberEntity:
|
||||
return memberEntity.ContentTypeIcon.IfNullOrWhiteSpace(Constants.Icons.Member);
|
||||
case IContentEntitySlim contentEntity:
|
||||
// NOTE: this case covers both content and media entities
|
||||
return contentEntity.ContentTypeIcon;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -380,8 +380,8 @@ namespace Umbraco.Web.Models.Mapping
|
||||
.ToDictionary(x => x.Key, x => (IEnumerable<Permission>)x.ToArray());
|
||||
}
|
||||
|
||||
private static string MapContentTypeIcon(EntitySlim entity)
|
||||
=> entity is ContentEntitySlim contentEntity ? contentEntity.ContentTypeIcon : null;
|
||||
private static string MapContentTypeIcon(IEntitySlim entity)
|
||||
=> entity is IContentEntitySlim contentEntity ? contentEntity.ContentTypeIcon : null;
|
||||
|
||||
private IEnumerable<EntityBasic> GetStartNodes(int[] startNodeIds, UmbracoObjectTypes objectType, string localizedKey, MapperContext context)
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Umbraco.Web.Trees
|
||||
if (id == Constants.System.RootString)
|
||||
{
|
||||
//get all blueprint content types
|
||||
var contentTypeAliases = entities.Select(x => ((ContentEntitySlim) x).ContentTypeAlias).Distinct();
|
||||
var contentTypeAliases = entities.Select(x => ((IContentEntitySlim) x).ContentTypeAlias).Distinct();
|
||||
//get the ids
|
||||
var contentTypeIds = Services.ContentTypeService.GetAllContentTypeIds(contentTypeAliases.ToArray()).ToArray();
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Umbraco.Web.Trees
|
||||
var ct = Services.ContentTypeService.Get(intId.Result);
|
||||
if (ct == null) return nodes;
|
||||
|
||||
var blueprintsForDocType = entities.Where(x => ct.Alias == ((ContentEntitySlim) x).ContentTypeAlias);
|
||||
var blueprintsForDocType = entities.Where(x => ct.Alias == ((IContentEntitySlim) x).ContentTypeAlias);
|
||||
nodes.AddRange(blueprintsForDocType
|
||||
.Select(entity =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user