Updates the versionable repo (content, members, media) to far more efficiently load in property and pre-value data, in fact the performance tests have show that this improves performance even more! The real underlying reason for these changes is so that we don't end up with a giant SQL 'IN' clause for these queries, and that these queries are far faster than IN clause queries.

This commit is contained in:
Shannon
2014-09-11 16:04:16 +10:00
parent 5195822435
commit d3bfb5e94d
6 changed files with 207 additions and 192 deletions

View File

@@ -75,13 +75,13 @@ namespace Umbraco.Core.Persistence.Repositories
.Where(GetBaseWhereClause(), new { Id = id })
.Where<DocumentDto>(x => x.Newest)
.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
var dto = Database.Fetch<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql).FirstOrDefault();
if (dto == null)
return null;
var content = CreateContentFromDto(dto, dto.ContentVersionDto.VersionId);
var content = CreateContentFromDto(dto, dto.ContentVersionDto.VersionId, sql);
return content;
}
@@ -93,10 +93,9 @@ namespace Umbraco.Core.Persistence.Repositories
{
sql.Where("umbracoNode.id in (@ids)", new {ids = ids});
}
else
{
sql.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
}
//we only want the newest ones with this method
sql.Where<DocumentDto>(x => x.Newest);
return ProcessQuery(sql);
}
@@ -178,8 +177,8 @@ namespace Umbraco.Core.Persistence.Repositories
if (dto == null)
return null;
var content = CreateContentFromDto(dto, versionId);
var content = CreateContentFromDto(dto, versionId, sql);
return content;
}
@@ -525,7 +524,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
else
{
yield return CreateContentFromDto(dto, dto.VersionId);
yield return CreateContentFromDto(dto, dto.VersionId, sql);
}
}
}
@@ -731,9 +730,11 @@ namespace Umbraco.Core.Persistence.Repositories
var dtos = Database.Fetch<DocumentDto, ContentVersionDto, ContentDto, NodeDto>(sql);
//content types
//NOTE: This should be ok for an SQL 'IN' statement, there shouldn't be an insane amount of content types
var contentTypes = _contentTypeRepository.GetAll(dtos.Select(x => x.ContentVersionDto.ContentDto.ContentTypeId).ToArray())
.ToArray();
//NOTE: This should be ok for an SQL 'IN' statement, there shouldn't be an insane amount of content types
var templates = _templateRepository.GetAll(
dtos
.Where(dto => dto.TemplateId.HasValue && dto.TemplateId.Value > 0)
@@ -741,19 +742,18 @@ namespace Umbraco.Core.Persistence.Repositories
.ToArray();
//Go get the property data for each document
var docDefs = dtos.Select(dto => new Tuple<int, Guid, IContentTypeComposition, DateTime, DateTime>(
var docDefs = dtos.Select(dto => new DocumentDefinition(
dto.NodeId,
dto.VersionId,
contentTypes.First(ct => ct.Id == dto.ContentVersionDto.ContentDto.ContentTypeId),
dto.ContentVersionDto.VersionDate,
dto.ContentVersionDto.ContentDto.NodeDto.CreateDate,
dto.ContentVersionDto.VersionDate))
contentTypes.First(ct => ct.Id == dto.ContentVersionDto.ContentDto.ContentTypeId)))
.ToArray();
var propertyData = GetPropertyCollection(docDefs);
var propertyData = GetPropertyCollection(sql, docDefs);
return dtos.Select(dto => CreateContentFromDto(
dto,
dto.ContentVersionDto.VersionId,
contentTypes.First(ct => ct.Id == dto.ContentVersionDto.ContentDto.ContentTypeId),
templates.FirstOrDefault(tem => tem.Id == (dto.TemplateId.HasValue ? dto.TemplateId.Value : -1)),
propertyData[dto.NodeId]));
@@ -763,18 +763,15 @@ namespace Umbraco.Core.Persistence.Repositories
/// Private method to create a content object from a DocumentDto, which is used by Get and GetByVersion.
/// </summary>
/// <param name="dto"></param>
/// <param name="versionId"></param>
/// <param name="contentType"></param>
/// <param name="template"></param>
/// <param name="propCollection"></param>
/// <returns></returns>
private IContent CreateContentFromDto(DocumentDto dto, Guid versionId,
IContentType contentType = null,
ITemplate template = null,
Models.PropertyCollection propCollection = null)
private IContent CreateContentFromDto(DocumentDto dto,
IContentType contentType,
ITemplate template,
Models.PropertyCollection propCollection)
{
contentType = contentType ?? _contentTypeRepository.Get(dto.ContentVersionDto.ContentDto.ContentTypeId);
var factory = new ContentFactory(contentType, NodeObjectTypeId, dto.NodeId);
var content = factory.BuildEntity(dto);
@@ -784,8 +781,39 @@ namespace Umbraco.Core.Persistence.Repositories
content.Template = template ?? _templateRepository.Get(dto.TemplateId.Value);
}
content.Properties = propCollection ??
GetPropertyCollection(dto.NodeId, versionId, contentType, content.CreateDate, content.UpdateDate);
content.Properties = propCollection;
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((Entity)content).ResetDirtyProperties(false);
return content;
}
/// <summary>
/// Private method to create a content object from a DocumentDto, which is used by Get and GetByVersion.
/// </summary>
/// <param name="dto"></param>
/// <param name="versionId"></param>
/// <param name="docSql"></param>
/// <returns></returns>
private IContent CreateContentFromDto(DocumentDto dto, Guid versionId, Sql docSql)
{
var contentType = _contentTypeRepository.Get(dto.ContentVersionDto.ContentDto.ContentTypeId);
var factory = new ContentFactory(contentType, NodeObjectTypeId, dto.NodeId);
var content = factory.BuildEntity(dto);
//Check if template id is set on DocumentDto, and get ITemplate if it is.
if (dto.TemplateId.HasValue && dto.TemplateId.Value > 0)
{
content.Template = _templateRepository.Get(dto.TemplateId.Value);
}
var docDef = new DocumentDefinition(dto.NodeId, versionId, content.UpdateDate, content.CreateDate, contentType);
var properties = GetPropertyCollection(docSql, docDef);
content.Properties = properties[dto.NodeId];
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946

View File

@@ -66,7 +66,7 @@ namespace Umbraco.Core.Persistence.Repositories
if (dto == null)
return null;
var content = CreateMediaFromDto(dto, dto.VersionId);
var content = CreateMediaFromDto(dto, dto.VersionId, sql);
return content;
}
@@ -78,10 +78,6 @@ namespace Umbraco.Core.Persistence.Repositories
{
sql.Where("umbracoNode.id in (@ids)", new { ids = ids });
}
else
{
sql.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
}
return ProcessQuery(sql);
}
@@ -164,7 +160,9 @@ namespace Umbraco.Core.Persistence.Repositories
var factory = new MediaFactory(mediaType, NodeObjectTypeId, dto.NodeId);
var media = factory.BuildEntity(dto);
media.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, mediaType, media.CreateDate, media.UpdateDate);
var properties = GetPropertyCollection(sql, new DocumentDefinition(dto.NodeId, dto.VersionId, media.UpdateDate, media.CreateDate, mediaType));
media.Properties = properties[dto.NodeId];
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
@@ -450,19 +448,18 @@ namespace Umbraco.Core.Persistence.Repositories
.ToArray();
//Go get the property data for each document
var docDefs = dtos.Select(dto => new Tuple<int, Guid, IContentTypeComposition, DateTime, DateTime>(
var docDefs = dtos.Select(dto => new DocumentDefinition(
dto.NodeId,
dto.VersionId,
contentTypes.First(ct => ct.Id == dto.ContentDto.ContentTypeId),
dto.VersionDate,
dto.ContentDto.NodeDto.CreateDate,
dto.VersionDate))
contentTypes.First(ct => ct.Id == dto.ContentDto.ContentTypeId)))
.ToArray();
var propertyData = GetPropertyCollection(docDefs);
var propertyData = GetPropertyCollection(sql, docDefs);
return dtos.Select(dto => CreateMediaFromDto(
dto,
dto.VersionId,
contentTypes.First(ct => ct.Id == dto.ContentDto.ContentTypeId),
propertyData[dto.NodeId]));
}
@@ -497,21 +494,43 @@ namespace Umbraco.Core.Persistence.Repositories
/// Private method to create a media object from a ContentDto
/// </summary>
/// <param name="dto"></param>
/// <param name="versionId"></param>
/// <param name="contentType"></param>
/// <param name="propCollection"></param>
/// <returns></returns>
private IMedia CreateMediaFromDto(ContentVersionDto dto, Guid versionId,
IMediaType contentType = null,
Models.PropertyCollection propCollection = null)
private IMedia CreateMediaFromDto(ContentVersionDto dto,
IMediaType contentType,
PropertyCollection propCollection)
{
contentType = contentType ?? _mediaTypeRepository.Get(dto.ContentDto.ContentTypeId);
var factory = new MediaFactory(contentType, NodeObjectTypeId, dto.NodeId);
var media = factory.BuildEntity(dto);
media.Properties = propCollection;
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946
((Entity)media).ResetDirtyProperties(false);
return media;
}
/// <summary>
/// Private method to create a media object from a ContentDto
/// </summary>
/// <param name="dto"></param>
/// <param name="versionId"></param>
/// <param name="docSql"></param>
/// <returns></returns>
private IMedia CreateMediaFromDto(ContentVersionDto dto, Guid versionId, Sql docSql)
{
var contentType = _mediaTypeRepository.Get(dto.ContentDto.ContentTypeId);
var factory = new MediaFactory(contentType, NodeObjectTypeId, dto.NodeId);
var media = factory.BuildEntity(dto);
media.Properties = propCollection ??
GetPropertyCollection(dto.NodeId, versionId, contentType, media.CreateDate, media.UpdateDate);
var docDef = new DocumentDefinition(dto.NodeId, versionId, media.UpdateDate, media.CreateDate, contentType);
var properties = GetPropertyCollection(docSql, docDef);
media.Properties = properties[dto.NodeId];
//on initial construction we don't want to have dirty properties tracked
// http://issues.umbraco.org/issue/U4-1946

View File

@@ -65,7 +65,7 @@ namespace Umbraco.Core.Persistence.Repositories
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
new PropertyDataRelator().Map, sql);
return BuildFromDto(dtos);
return BuildFromDto(dtos, sql);
}
protected override IEnumerable<IMember> PerformGetAll(params int[] ids)
@@ -82,7 +82,7 @@ namespace Umbraco.Core.Persistence.Repositories
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
new PropertyDataRelator().Map, sql);
return BuildFromDtos(dtos);
return BuildFromDtos(dtos, sql);
}
protected override IEnumerable<IMember> PerformGetByQuery(IQuery<IMember> query)
@@ -99,7 +99,7 @@ namespace Umbraco.Core.Persistence.Repositories
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
new PropertyDataRelator().Map, sql);
return BuildFromDtos(dtos);
return BuildFromDtos(dtos, sql);
}
#endregion
@@ -439,7 +439,7 @@ namespace Umbraco.Core.Persistence.Repositories
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
new PropertyDataRelator().Map, sql);
return BuildFromDto(dtos);
return BuildFromDto(dtos, sql);
}
protected override void PerformDeleteVersion(int id, Guid versionId)
@@ -523,7 +523,7 @@ namespace Umbraco.Core.Persistence.Repositories
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
new PropertyDataRelator().Map, sql);
return BuildFromDtos(dtos);
return BuildFromDtos(dtos, sql);
}
public bool Exists(string username)
@@ -640,7 +640,7 @@ namespace Umbraco.Core.Persistence.Repositories
_contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity<IMember>(previewExists, content, xml));
}
private IMember BuildFromDto(List<MemberReadOnlyDto> dtos)
private IMember BuildFromDto(List<MemberReadOnlyDto> dtos, Sql docSql)
{
if (dtos == null || dtos.Any() == false)
return null;
@@ -657,18 +657,22 @@ namespace Umbraco.Core.Persistence.Repositories
var factory = new MemberReadOnlyFactory(memberTypes);
var member = factory.BuildEntity(dto);
member.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, member.ContentType, dto.CreateDate, dto.UpdateDate);
var properties = GetPropertyCollection(docSql, new DocumentDefinition(dto.NodeId, dto.VersionId, dto.UpdateDate, dto.CreateDate, member.ContentType));
member.Properties = properties[dto.NodeId];
return member;
}
private IEnumerable<IMember> BuildFromDtos(List<MemberReadOnlyDto> dtos)
private IEnumerable<IMember> BuildFromDtos(List<MemberReadOnlyDto> dtos, Sql docSql)
{
if (dtos == null || dtos.Any() == false)
return Enumerable.Empty<IMember>();
//We assume that there won't exist a lot of MemberTypes, so the following should be fairly fast
var memberTypes = new Dictionary<string, IMemberType>();
//TODO: We should do an SQL 'IN' here
var memberTypeList = _memberTypeRepository.GetAll();
memberTypeList.ForEach(x => memberTypes.Add(x.Alias, x));
@@ -677,7 +681,11 @@ namespace Umbraco.Core.Persistence.Repositories
foreach (var dto in dtos)
{
var entity = factory.BuildEntity(dto);
entity.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, entity.ContentType, dto.CreateDate, dto.UpdateDate);
var properties = GetPropertyCollection(docSql,new DocumentDefinition(dto.NodeId, dto.VersionId, dto.UpdateDate, dto.CreateDate, entity.ContentType));
entity.Properties = properties[dto.NodeId];
entities.Add(entity);
}
return entities;

View File

@@ -218,154 +218,66 @@ namespace Umbraco.Core.Persistence.Repositories
}
}
}
/// <summary>
/// This is a fix for U4-1407 - when property types are added to a content type - the property of the entity are not actually created
/// and we get YSODs
/// </summary>
/// <param name="id"></param>
/// <param name="versionId"></param>
/// <param name="contentType"></param>
/// <param name="createDate"></param>
/// <param name="updateDate"></param>
/// <returns></returns>
protected PropertyCollection GetPropertyCollection(int id, Guid versionId, IContentTypeComposition contentType, DateTime createDate, DateTime updateDate)
{
var sql = new Sql();
sql.Select("cmsPropertyData.*, cmsDataTypePreValues.id as preValId, cmsDataTypePreValues.value, cmsDataTypePreValues.sortorder, cmsDataTypePreValues.alias, cmsDataTypePreValues.datatypeNodeId")
.From<PropertyDataDto>()
.InnerJoin<PropertyTypeDto>()
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
.LeftOuterJoin<DataTypePreValueDto>()
.On<PropertyTypeDto, DataTypePreValueDto>(left => left.DataTypeId, right => right.DataTypeNodeId)
.Where<PropertyDataDto>(x => x.NodeId == id)
.Where<PropertyDataDto>(x => x.VersionId == versionId);
var allData = Database.Fetch<dynamic>(sql);
var propertyDataDtos = allData.Select(x => new PropertyDataDto
{
Date = x.dataDate,
Id = x.id,
Integer = x.dataInt,
NodeId = x.contentNodeId,
Text = x.dataNtext,
VarChar = x.dataNvarchar,
VersionId = x.versionId,
PropertyTypeId = x.propertytypeid,
//NOTE: This get's used for nothing so we don't need to map it
//PropertyTypeDto = new PropertyTypeDto()
}).Distinct();
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
var properties = propertyFactory.BuildEntity(propertyDataDtos).ToArray();
var newProperties = properties.Where(x => x.HasIdentity == false && x.PropertyType.HasIdentity);
foreach (var property in newProperties)
{
var propertyDataDto = new PropertyDataDto { NodeId = id, PropertyTypeId = property.PropertyTypeId, VersionId = versionId };
int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
property.Version = versionId;
property.Id = primaryKey;
}
foreach (var property in properties)
{
//NOTE: The benchmarks run with and without the following code show very little change so this is not a perf bottleneck
var editor = PropertyEditorResolver.Current.GetByAlias(property.PropertyType.PropertyEditorAlias);
var tagSupport = TagExtractor.GetAttribute(editor);
if (tagSupport != null)
{
//this property has tags, so we need to extract them and for that we need the prevals which we've already looked up
var preValData = allData.Where(x => x.propertytypeid == property.PropertyTypeId && x.preValId != null)
.Select(x => new DataTypePreValueDto
{
Alias = x.alias,
DataTypeNodeId = x.datatypeNodeId,
Id = x.preValId,
SortOrder = x.sortorder,
Value = x.value
})
.Distinct()
.ToArray();
var asDictionary = preValData.ToDictionary(x => x.Alias, x => new PreValue(x.Id, x.Value, x.SortOrder));
var preVals = new PreValueCollection(asDictionary);
var contentPropData = new ContentPropertyData(property.Value,
preVals,
new Dictionary<string, object>());
TagExtractor.SetPropertyTags(property, contentPropData, property.Value, tagSupport);
}
}
return new PropertyCollection(properties);
}
protected IDictionary<int, PropertyCollection> GetPropertyCollection(
Tuple<int, Guid, IContentTypeComposition, DateTime, DateTime>[] documentDefs)
Sql docSql,
params DocumentDefinition[] documentDefs)
{
if (documentDefs.Length <= 0) return new Dictionary<int, PropertyCollection>();
//FIXME: we need to split on 2100 max SQL server parameters
// since there will be 2 params per single row it will be half that amount
if ((documentDefs.Length / 2) > 2000)
throw new InvalidOperationException("Cannot perform this lookup, too many sql parameters");
//we need to parse the original SQL statement and reduce the columns to just cmsContent.nodeId, cmsContentVersion.VersionId so that we can use
// the statement to go get the property data for all of the items by using an inner join
var parsedOriginalSql = "SELECT {0} " + docSql.SQL.Substring(docSql.SQL.IndexOf("FROM", StringComparison.Ordinal));
//now remove everything from an Orderby clause and beyond
if (parsedOriginalSql.InvariantContains("ORDER BY "))
{
parsedOriginalSql = parsedOriginalSql.Substring(0, parsedOriginalSql.IndexOf("ORDER BY ", System.StringComparison.Ordinal));
}
var sql = new Sql();
sql.Select("cmsPropertyData.*, cmsDataTypePreValues.id as preValId, cmsDataTypePreValues.value, cmsDataTypePreValues.sortorder, cmsDataTypePreValues.alias, cmsDataTypePreValues.datatypeNodeId")
.From<PropertyDataDto>()
.InnerJoin<PropertyTypeDto>()
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
var propSql = new Sql(@"SELECT cmsPropertyData.*
FROM cmsPropertyData
INNER JOIN cmsPropertyType
ON cmsPropertyData.propertytypeid = cmsPropertyType.id
INNER JOIN
(" + string.Format(parsedOriginalSql, "cmsContent.nodeId, cmsContentVersion.VersionId") + @") as docData
ON cmsPropertyData.versionId = docData.VersionId AND cmsPropertyData.contentNodeId = docData.nodeId
LEFT OUTER JOIN cmsDataTypePreValues
ON cmsPropertyType.dataTypeId = cmsDataTypePreValues.datatypeNodeId", docSql.Arguments);
.LeftOuterJoin<DataTypePreValueDto>()
.On<PropertyTypeDto, DataTypePreValueDto>(left => left.DataTypeId, right => right.DataTypeNodeId)
.Where("cmsPropertyData.contentNodeId IN (@nodeIds) AND cmsPropertyData.versionId IN (@versionIds)",
new { nodeIds = documentDefs.Select(x => x.Item1), versionIds = documentDefs.Select(x => x.Item2) });
var allPropertyData = Database.Fetch<PropertyDataDto>(propSql);
var allData = Database.Fetch<dynamic>(sql);
//This is a lazy access call to get all prevalue data for the data types that make up all of these properties which we use
// below if any property requires tag support
var allPreValues = new Lazy<IEnumerable<DataTypePreValueDto>>(() =>
{
var preValsSql = new Sql(@"SELECT DISTINCT
cmsDataTypePreValues.id as preValId, cmsDataTypePreValues.value, cmsDataTypePreValues.sortorder, cmsDataTypePreValues.alias, cmsDataTypePreValues.datatypeNodeId
FROM cmsDataTypePreValues
INNER JOIN cmsPropertyType
ON cmsDataTypePreValues.datatypeNodeId = cmsPropertyType.dataTypeId
INNER JOIN
(" + string.Format(parsedOriginalSql, "cmsContent.contentType") + @") as docData
ON cmsPropertyType.contentTypeId = docData.contentType", docSql.Arguments);
return Database.Fetch<DataTypePreValueDto>(preValsSql);
});
var result = new Dictionary<int, PropertyCollection>();
foreach (var def in documentDefs)
{
var propertyDataDtos = allData.Select(x => new PropertyDataDto
{
Date = x.dataDate,
Id = x.id,
Integer = x.dataInt,
NodeId = x.contentNodeId,
Text = x.dataNtext,
VarChar = x.dataNvarchar,
VersionId = x.versionId,
PropertyTypeId = x.propertytypeid,
//NOTE: This get's used for nothing so we don't need to map it
//PropertyTypeDto = new PropertyTypeDto()
})
.Where(x => x.NodeId == def.Item1)
.Distinct();
var propertyDataDtos = allPropertyData.Where(x => x.NodeId == def.Id).Distinct();
var propertyFactory = new PropertyFactory(def.Item3, def.Item2, def.Item1, def.Item4, def.Item5);
var propertyFactory = new PropertyFactory(def.Composition, def.Version, def.Id, def.CreateDate, def.VersionDate);
var properties = propertyFactory.BuildEntity(propertyDataDtos).ToArray();
var newProperties = properties.Where(x => x.HasIdentity == false && x.PropertyType.HasIdentity);
foreach (var property in newProperties)
{
var propertyDataDto = new PropertyDataDto { NodeId = def.Item1, PropertyTypeId = property.PropertyTypeId, VersionId = def.Item2 };
var propertyDataDto = new PropertyDataDto { NodeId = def.Id, PropertyTypeId = property.PropertyTypeId, VersionId = def.Version };
int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
property.Version = def.Item2;
property.Version = def.Version;
property.Id = primaryKey;
}
@@ -377,18 +289,8 @@ namespace Umbraco.Core.Persistence.Repositories
if (tagSupport != null)
{
//this property has tags, so we need to extract them and for that we need the prevals which we've already looked up
var preValData = allData.Where(x => x.propertytypeid == property.PropertyTypeId && x.preValId != null)
.Select(x => new DataTypePreValueDto
{
Alias = x.alias,
DataTypeNodeId = x.datatypeNodeId,
Id = x.preValId,
SortOrder = x.sortorder,
Value = x.value
})
var preValData = allPreValues.Value.Where(x => x.DataTypeNodeId == property.PropertyType.DataTypeDefinitionId)
.Distinct()
.ToArray();
@@ -404,11 +306,32 @@ namespace Umbraco.Core.Persistence.Repositories
}
}
result.Add(def.Item1, new PropertyCollection(properties));
result.Add(def.Id, new PropertyCollection(properties));
}
return result;
}
public class DocumentDefinition
{
/// <summary>
/// Initializes a new instance of the <see cref="T:System.Object"/> class.
/// </summary>
public DocumentDefinition(int id, Guid version, DateTime versionDate, DateTime createDate, IContentTypeComposition composition)
{
Id = id;
Version = version;
VersionDate = versionDate;
CreateDate = createDate;
Composition = composition;
}
public int Id { get; set; }
public Guid Version { get; set; }
public DateTime VersionDate { get; set; }
public DateTime CreateDate { get; set; }
public IContentTypeComposition Composition { get; set; }
}
}
}

View File

@@ -332,6 +332,37 @@ namespace Umbraco.Tests.Persistence.Repositories
}
}
[Test]
public void Can_Perform_Get_All_With_Many_Version()
{
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
ContentTypeRepository contentTypeRepository;
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository))
{
var result = repository.GetAll().ToArray();
foreach (var content in result)
{
content.ChangePublishedState(PublishedState.Saved);
repository.AddOrUpdate(content);
}
unitOfWork.Commit();
foreach (var content in result)
{
content.ChangePublishedState(PublishedState.Published);
repository.AddOrUpdate(content);
}
unitOfWork.Commit();
//re-get
var result2 = repository.GetAll().ToArray();
Assert.AreEqual(result.Count(), result2.Count());
}
}
[Test]
public void Can_Perform_GetPagedResultsByQuery_ForFirstPage_On_ContentRepository()
{

View File

@@ -38,7 +38,13 @@ namespace Umbraco.Tests.Services
public void Retrieving_All_Content_In_Site()
{
//NOTE: Doing this the old 1 by 1 way and based on the results of the ContentServicePerformanceTest.Retrieving_All_Content_In_Site
// the old way takes 143795ms, the new above way takes: 14249ms that is a 90% savings of processing and sql calls!
// the old way takes 143795ms, the new above way takes:
// 14249ms
//
// ... NOPE, made some new changes, it is now....
// 5290ms !!!!!!
//
// that is a 96% savings of processing and sql calls!
var contentType1 = MockedContentTypes.CreateTextpageContentType("test1", "test1");
var contentType2 = MockedContentTypes.CreateTextpageContentType("test2", "test2");