diff --git a/src/Umbraco.Core/Models/UmbracoObjectTypes.cs b/src/Umbraco.Core/Models/UmbracoObjectTypes.cs
index e04e20ff0a..c9967c0688 100644
--- a/src/Umbraco.Core/Models/UmbracoObjectTypes.cs
+++ b/src/Umbraco.Core/Models/UmbracoObjectTypes.cs
@@ -61,6 +61,7 @@ namespace Umbraco.Core.Models
[FriendlyName("Member Group")]
MemberGroup,
+ //TODO: What is a 'Content Item' supposed to be???
///
/// Content Item
///
diff --git a/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs b/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs
index ec3f48a0ca..e42397e11c 100644
--- a/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs
+++ b/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs
@@ -1,13 +1,29 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Linq;
+using System.Reflection;
using Umbraco.Core.Models;
+using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence.Repositories;
namespace Umbraco.Core.Persistence.Factories
{
internal class UmbracoEntityFactory : IEntityFactory
{
+ internal void AddAdditionalData(UmbracoEntity entity, IDictionary originalEntityProperties)
+ {
+ var entityProps = TypeHelper.GetPublicProperties(typeof(IUmbracoEntity)).Select(x => x.Name).ToArray();
+
+ //figure out what extra properties we have that are not on the IUmbracoEntity and add them to additional data
+ foreach (var k in originalEntityProperties.Keys
+ .Select(x => new { orig = x, title = x.ConvertCase(StringAliasCaseType.PascalCase) })
+ .Where(x => entityProps.InvariantContains(x.title) == false))
+ {
+ entity.AdditionalData[k.title] = originalEntityProperties[k.orig];
+ }
+ }
+
internal UmbracoEntity BuildEntityFromDynamic(dynamic d)
{
var entity = new UmbracoEntity(d.trashed)
@@ -38,12 +54,18 @@ namespace Umbraco.Core.Persistence.Factories
Guid.TryParse(d.publishedVersion.ToString(), out publishedVersion);
}
var newestVersion = default(Guid);
- Guid.TryParse(d.newestVersion.ToString(), out newestVersion);
+ if (d.newestVersion != null)
+ {
+ Guid.TryParse(d.newestVersion.ToString(), out newestVersion);
+ }
entity.IsPublished = publishedVersion != default(Guid) || (newestVersion != default(Guid) && publishedVersion == newestVersion);
entity.IsDraft = newestVersion != default(Guid) && (publishedVersion == default(Guid) || publishedVersion != newestVersion);
entity.HasPendingChanges = (publishedVersion != default(Guid) && newestVersion != default(Guid)) && publishedVersion != newestVersion;
-
+
+ //Now we can assign the additional data!
+ AddAdditionalData(entity, asDictionary);
+
return entity;
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
index 0fd0fc4e76..7336e36ab7 100644
--- a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
@@ -52,12 +52,12 @@ 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 = _work.Database.FirstOrDefault(sql);
if (nodeDto == null)
return null;
var factory = new UmbracoEntityFactory();
- var entity = factory.BuildEntity(nodeDto);
+ var entity = factory.BuildEntityFromDynamic(nodeDto);
return entity;
}
@@ -67,12 +67,12 @@ namespace Umbraco.Core.Persistence.Repositories
bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document);
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
var sql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, key).Append(GetGroupBy(isContent, isMedia));
- var nodeDto = _work.Database.FirstOrDefault(sql);
+ var nodeDto = _work.Database.FirstOrDefault(sql);
if (nodeDto == null)
return null;
var factory = new UmbracoEntityFactory();
- var entity = factory.BuildEntity(nodeDto);
+ var entity = factory.BuildEntityFromDynamic(nodeDto);
return entity;
}
@@ -80,12 +80,12 @@ 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 = _work.Database.FirstOrDefault(sql);
if (nodeDto == null)
return null;
var factory = new UmbracoEntityFactory();
- var entity = factory.BuildEntity(nodeDto);
+ var entity = factory.BuildEntityFromDynamic(nodeDto);
return entity;
}
@@ -95,12 +95,13 @@ namespace Umbraco.Core.Persistence.Repositories
bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document);
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
var sql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, id).Append(GetGroupBy(isContent, isMedia));
- var nodeDto = _work.Database.FirstOrDefault(sql);
+
+ var nodeDto = _work.Database.FirstOrDefault(sql);
if (nodeDto == null)
return null;
var factory = new UmbracoEntityFactory();
- var entity = factory.BuildEntity(nodeDto);
+ var entity = factory.BuildEntityFromDynamic(nodeDto);
return entity;
}
@@ -119,16 +120,27 @@ namespace Umbraco.Core.Persistence.Repositories
bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document);
bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media);
var sql = GetBaseWhere(GetBase, isContent, isMedia, string.Empty, objectTypeId).Append(GetGroupBy(isContent, isMedia));
- var dtos = isMedia
- ? _work.Database.Fetch(
- new UmbracoEntityRelator().Map, sql)
- : _work.Database.Fetch(sql);
+
var factory = new UmbracoEntityFactory();
- foreach (var dto in dtos)
+ if (isMedia)
{
- var entity = factory.BuildEntity(dto);
- yield return entity;
+ //for now treat media differently
+ //TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields
+ var entities = _work.Database.Fetch(
+ new UmbracoEntityRelator().Map, sql);
+ foreach (var entity in entities)
+ {
+ yield return entity;
+ }
+ }
+ else
+ {
+ var dtos = _work.Database.Fetch(sql);
+ foreach (var entity in dtos.Select(dto => factory.BuildEntityFromDynamic(dto)))
+ {
+ yield return entity;
+ }
}
}
}
@@ -140,10 +152,10 @@ 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 = _work.Database.Fetch(sql);
var factory = new UmbracoEntityFactory();
- var list = dtos.Select(factory.BuildEntity).Cast().ToList();
+ var list = dtos.Select(factory.BuildEntityFromDynamic).Cast().ToList();
return list;
}
@@ -162,42 +174,22 @@ namespace Umbraco.Core.Persistence.Repositories
if (isMedia)
{
- //treat media differently for now
- var dtos = _work.Database.Fetch(
+ //treat media differently for now
+ //TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields
+ var entities = _work.Database.Fetch(
new UmbracoEntityRelator().Map, sql);
- return dtos.Select(factory.BuildEntity).Cast().ToArray();
+ return entities;
}
else
{
- //use dynamic so that we can get ALL properties from the SQL
- //we'll have to stitch stuff together manually but we can get our
- //additional data to put in the dictionary.
+ //use dynamic so that we can get ALL properties from the SQL so we can chuck that data into our AdditionalData
var dtos = _work.Database.Fetch(sql);
- var entityProps = TypeHelper.GetPublicProperties(typeof (IUmbracoEntity)).Select(x => x.Name).ToArray();
- var result = new List();
- foreach (var d in dtos)
- {
- //build the initial entity
- IUmbracoEntity entity = factory.BuildEntityFromDynamic(d);
-
- //convert the dynamic row to dictionary
- var asDictionary = (IDictionary) d;
-
- //figure out what extra properties we have that are not on the IUmbracoEntity and add them to additional data
- foreach (var k in asDictionary.Keys
- .Select(x => new {orig = x, title = x.ConvertCase(StringAliasCaseType.PascalCase)})
- .Where(x => entityProps.InvariantContains(x.title) == false))
- {
- entity.AdditionalData[k.title] = asDictionary[k.orig];
- }
-
- result.Add(entity);
- }
- return result;
+ return dtos.Select(factory.BuildEntityFromDynamic).Cast().ToList();
}
}
#endregion
+
#region Sql Statements
@@ -396,11 +388,20 @@ namespace Umbraco.Core.Persistence.Repositories
public string UmbracoFile { get; set; }
}
+ ///
+ /// This is a special relator in that it is not returning a DTO but a real resolved entity and that it accepts
+ /// a dynamic instance.
+ ///
+ ///
+ /// We're doing this because when we query the db, we want to use dynamic so that it returns all available fields not just the ones
+ /// defined on the entity so we can them to additional data
+ ///
internal class UmbracoEntityRelator
{
- internal UmbracoEntityDto Current;
+ internal UmbracoEntity Current;
+ private readonly UmbracoEntityFactory _factory = new UmbracoEntityFactory();
- internal UmbracoEntityDto Map(UmbracoEntityDto a, UmbracoPropertyDto p)
+ internal UmbracoEntity Map(dynamic a, UmbracoPropertyDto p)
{
// Terminating call. Since we can return null from this function
// we need to be ready for PetaPoco to callback later with null
@@ -408,28 +409,44 @@ namespace Umbraco.Core.Persistence.Repositories
if (a == null)
return Current;
- // Is this the same UmbracoEntityDto as the current one we're processing
- if (Current != null && Current.UniqueId == a.UniqueId)
+ // Is this the same UmbracoEntity as the current one we're processing
+ if (Current != null && Current.Key == a.uniqueID)
{
- // Yes, just add this UmbracoPropertyDto to the current UmbracoEntityDto's collection
- Current.UmbracoPropertyDtos.Add(p);
-
- // Return null to indicate we're not done with this UmbracoEntityDto yet
+ // Yes, just add this UmbracoProperty to the current UmbracoEntity's collection
+ if (Current.UmbracoProperties == null)
+ {
+ Current.UmbracoProperties = new List();
+ }
+ Current.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty
+ {
+ PropertyEditorAlias = p.PropertyEditorAlias,
+ Value = p.UmbracoFile
+ });
+ // Return null to indicate we're not done with this UmbracoEntity yet
return null;
}
- // This is a different UmbracoEntityDto to the current one, or this is the
+ // This is a different UmbracoEntity to the current one, or this is the
// first time through and we don't have a Tab yet
// Save the current UmbracoEntityDto
var prev = Current;
- // Setup the new current UmbracoEntityDto
- Current = a;
- Current.UmbracoPropertyDtos = new List();
- Current.UmbracoPropertyDtos.Add(p);
+ // Setup the new current UmbracoEntity
+
+ Current = _factory.BuildEntityFromDynamic(a);
- // Return the now populated previous UmbracoEntityDto (or null if first time through)
+ //add the property/create the prop list if null
+ Current.UmbracoProperties = new List
+ {
+ new UmbracoEntity.UmbracoProperty
+ {
+ PropertyEditorAlias = p.PropertyEditorAlias,
+ Value = p.UmbracoFile
+ }
+ };
+
+ // Return the now populated previous UmbracoEntity (or null if first time through)
return prev;
}
}