diff --git a/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs b/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs index be0808bb19..4511ebe35d 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RelationRepository.cs @@ -42,34 +42,17 @@ namespace Umbraco.Core.Persistence.Repositories throw new Exception(string.Format("RelationType with Id: {0} doesn't exist", dto.RelationType)); var factory = new RelationFactory(relationType); - var entity = factory.BuildEntity(dto); - - //on initial construction we don't want to have dirty properties tracked - // http://issues.umbraco.org/issue/U4-1946 - ((TracksChangesEntityBase)entity).ResetDirtyProperties(false); - - return entity; + return DtoToEntity(dto, factory); } - //TODO: Fix N+1 ! - protected override IEnumerable PerformGetAll(params int[] ids) { - if (ids.Any()) - { - foreach (var id in ids) - { - yield return Get(id); - } - } - else - { - var dtos = Database.Fetch("WHERE id > 0"); - foreach (var dto in dtos) - { - yield return Get(dto.Id); - } - } + var sql = GetBaseQuery(false); + if (ids.Length > 0) + sql.WhereIn(x => x.Id, ids); + sql.OrderBy(x => x.RelationType); + var dtos = Database.Fetch(sql); + return DtosToEntities(dtos); } protected override IEnumerable PerformGetByQuery(IQuery query) @@ -77,13 +60,36 @@ namespace Umbraco.Core.Persistence.Repositories var sqlClause = GetBaseQuery(false); var translator = new SqlTranslator(sqlClause, query); var sql = translator.Translate(); - + sql.OrderBy(x => x.RelationType); var dtos = Database.Fetch(sql); + return DtosToEntities(dtos); + } - foreach (var dto in dtos) + private IEnumerable DtosToEntities(IEnumerable dtos) + { + // in most cases, the relation type will be the same for all of them, + // plus we've ordered the relations by type, so try to allocate as few + // factories as possible - bearing in mind that relation types are cached + RelationFactory factory = null; + var relationTypeId = -1; + + return dtos.Select(x => { - yield return Get(dto.Id); - } + if (relationTypeId != x.RelationType) + factory = new RelationFactory(_relationTypeRepository.Get(relationTypeId = x.RelationType)); + return DtoToEntity(x, factory); + }); + } + + private static IRelation DtoToEntity(RelationDto dto, RelationFactory factory) + { + var entity = factory.BuildEntity(dto); + + //on initial construction we don't want to have dirty properties tracked + // http://issues.umbraco.org/issue/U4-1946 + ((TracksChangesEntityBase)entity).ResetDirtyProperties(false); + + return entity; } #endregion