diff --git a/src/Umbraco.Core/CodeAnnotations/FriendlyNameAttribute.cs b/src/Umbraco.Core/CodeAnnotations/FriendlyNameAttribute.cs
new file mode 100644
index 0000000000..54d47cca17
--- /dev/null
+++ b/src/Umbraco.Core/CodeAnnotations/FriendlyNameAttribute.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace Umbraco.Core.CodeAnnotations
+{
+ ///
+ /// Attribute to add a Friendly Name string with an UmbracoObjectType enum value
+ ///
+ internal class FriendlyNameAttribute : Attribute
+ {
+ ///
+ /// friendly name value
+ ///
+ private readonly string _friendlyName;
+
+ ///
+ /// Initializes a new instance of the FriendlyNameAttribute class
+ /// Sets the friendly name value
+ ///
+ /// attribute value
+ public FriendlyNameAttribute(string friendlyName)
+ {
+ this._friendlyName = friendlyName;
+ }
+
+ ///
+ /// Gets the friendly name
+ ///
+ /// string of friendly name
+ public override string ToString()
+ {
+ return this._friendlyName;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/CodeAnnotations/UmbracoObjectTypeAttribute.cs b/src/Umbraco.Core/CodeAnnotations/UmbracoObjectTypeAttribute.cs
new file mode 100644
index 0000000000..e6f887a2c8
--- /dev/null
+++ b/src/Umbraco.Core/CodeAnnotations/UmbracoObjectTypeAttribute.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Umbraco.Core.CodeAnnotations
+{
+ ///
+ /// Attribute to associate a GUID string and Type with an UmbracoObjectType Enum value
+ ///
+ internal class UmbracoObjectTypeAttribute : Attribute
+ {
+ public UmbracoObjectTypeAttribute(string objectId)
+ {
+ ObjectId = new Guid(objectId);
+ }
+
+ public UmbracoObjectTypeAttribute(string objectId, Type modelType)
+ {
+ ObjectId = new Guid(objectId);
+ ModelType = modelType;
+ }
+
+ public Guid ObjectId { get; private set; }
+
+ public Type ModelType { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/UmbracoEntity.cs b/src/Umbraco.Core/Models/UmbracoEntity.cs
new file mode 100644
index 0000000000..6e29dda984
--- /dev/null
+++ b/src/Umbraco.Core/Models/UmbracoEntity.cs
@@ -0,0 +1,40 @@
+using System;
+using Umbraco.Core.Models.EntityBase;
+
+namespace Umbraco.Core.Models
+{
+ ///
+ /// Implementation of the for internal use.
+ ///
+ internal class UmbracoEntity : Entity, IUmbracoEntity
+ {
+ public UmbracoEntity()
+ {
+ }
+
+ public UmbracoEntity(bool trashed)
+ {
+ Trashed = trashed;
+ }
+
+ public int CreatorId { get; set; }
+
+ public int Level { get; set; }
+
+ public string Name { get; set; }
+
+ public int ParentId { get; set; }
+
+ public string Path { get; set; }
+
+ public int SortOrder { get; set; }
+
+ public bool Trashed { get; private set; }
+
+ public bool HasChildren { get; set; }
+
+ public bool IsPublished { get; set; }
+
+ public Guid NodeObjectTypeId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/UmbracoObjectTypes.cs b/src/Umbraco.Core/Models/UmbracoObjectTypes.cs
new file mode 100644
index 0000000000..e4121a22a1
--- /dev/null
+++ b/src/Umbraco.Core/Models/UmbracoObjectTypes.cs
@@ -0,0 +1,113 @@
+using Umbraco.Core.CodeAnnotations;
+
+namespace Umbraco.Core.Models
+{
+ ///
+ /// Enum used to represent the Umbraco Object Types and thier associated GUIDs
+ ///
+ public enum UmbracoObjectTypes
+ {
+ ///
+ /// Default value
+ ///
+ Unknown,
+
+ ///
+ /// Content Item Type
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.ContentItemType)]
+ [FriendlyName("Content Item Type")]
+ ContentItemType,
+
+ ///
+ /// Root
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.SystemRoot)]
+ [FriendlyName("Root")]
+ ROOT,
+
+ ///
+ /// Document
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.Document, typeof(IContent))]
+ [FriendlyName("Document")]
+ Document,
+
+ ///
+ /// Media
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.Media, typeof(IMedia))]
+ [FriendlyName("Media")]
+ Media,
+
+ ///
+ /// Member Type
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.MemberType)]
+ [FriendlyName("Member Type")]
+ MemberType,
+
+ ///
+ /// Template
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.Template, typeof(ITemplate))]
+ [FriendlyName("Template")]
+ Template,
+
+ ///
+ /// Member Group
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.MemberGroup)]
+ [FriendlyName("Member Group")]
+ MemberGroup,
+
+ ///
+ /// Content Item
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.ContentItem)]
+ [FriendlyName("Content Item")]
+ ContentItem,
+
+ ///
+ /// "Media Type
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.MediaType, typeof(IMediaType))]
+ [FriendlyName("Media Type")]
+ MediaType,
+
+ ///
+ /// Document Type
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.DocumentType, typeof(IContentType))]
+ [FriendlyName("Document Type")]
+ DocumentType,
+
+ ///
+ /// Recycle Bin
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.RecycleBin)]
+ [FriendlyName("Recycle Bin")]
+ RecycleBin,
+
+ ///
+ /// Stylesheet
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.Stylesheet)]
+ [FriendlyName("Stylesheet")]
+ Stylesheet,
+
+ ///
+ /// Member
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.Member)]
+ [FriendlyName("Member")]
+ Member,
+
+ ///
+ /// Data Type
+ ///
+ [UmbracoObjectTypeAttribute(Constants.ObjectTypes.DataType, typeof(IDataTypeDefinition))]
+ [FriendlyName("Data Type")]
+ DataType
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs b/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs
new file mode 100644
index 0000000000..af4476f394
--- /dev/null
+++ b/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs
@@ -0,0 +1,79 @@
+using System;
+using Umbraco.Core.CodeAnnotations;
+
+namespace Umbraco.Core.Models
+{
+ ///
+ /// Extension methods for the UmbracoObjectTypes enum
+ ///
+ public static class UmbracoObjectTypesExtensions
+ {
+ ///
+ /// Get an UmbracoObjectTypes value from it's name
+ ///
+ /// Enum value name
+ /// an UmbracoObjectTypes Enum value
+ public static UmbracoObjectTypes GetUmbracoObjectType(string name)
+ {
+ return (UmbracoObjectTypes)Enum.Parse(typeof(UmbracoObjectTypes), name, false);
+ }
+
+ ///
+ /// Get an instance of an UmbracoObjectTypes enum value from it's GUID
+ ///
+ /// Enum value GUID
+ /// an UmbracoObjectTypes Enum value
+ public static UmbracoObjectTypes GetUmbracoObjectType(Guid guid)
+ {
+ var umbracoObjectType = UmbracoObjectTypes.Unknown;
+
+ foreach (var name in Enum.GetNames(typeof(UmbracoObjectTypes)))
+ {
+ if (GetUmbracoObjectType(name).GetGuid() == guid)
+ {
+ umbracoObjectType = GetUmbracoObjectType(name);
+ }
+ }
+
+ return umbracoObjectType;
+ }
+
+ ///
+ /// Extension method for the UmbracoObjectTypes enum to return the enum GUID
+ ///
+ /// UmbracoObjectTypes Enum value
+ /// a GUID value of the UmbracoObjectTypes
+ public static Guid GetGuid(this UmbracoObjectTypes umbracoObjectType)
+ {
+ var attribute = umbracoObjectType.GetType().FirstAttribute();
+ if (attribute == null)
+ return Guid.Empty;
+
+ return attribute.ObjectId;
+ }
+
+ ///
+ /// Extension method for the UmbracoObjectTypes enum to return the enum name
+ ///
+ /// UmbracoObjectTypes value
+ /// The enum name of the UmbracoObjectTypes value
+ public static string GetName(this UmbracoObjectTypes umbracoObjectType)
+ {
+ return Enum.GetName(typeof(UmbracoObjectTypes), umbracoObjectType);
+ }
+
+ ///
+ /// Extension method for the UmbracoObejctTypes enum to return the enum friendly name
+ ///
+ /// UmbracoObjectTypes value
+ /// a string of the FriendlyName
+ public static string GetFriendlyName(this UmbracoObjectTypes umbracoObjectType)
+ {
+ var attribute = umbracoObjectType.GetType().FirstAttribute();
+ if (attribute == null)
+ return string.Empty;
+
+ return attribute.ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs b/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs
new file mode 100644
index 0000000000..41ce480a44
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs
@@ -0,0 +1,48 @@
+using System.Globalization;
+using Umbraco.Core.Models;
+using Umbraco.Core.Models.Rdbms;
+
+namespace Umbraco.Core.Persistence.Factories
+{
+ internal class UmbracoEntityFactory : IEntityFactory
+ {
+ public UmbracoEntity BuildEntity(NodeDto dto)
+ {
+ var entity = new UmbracoEntity(dto.Trashed)
+ {
+ CreateDate = dto.CreateDate,
+ CreatorId = dto.UserId.Value,
+ Id = dto.NodeId,
+ Key = dto.UniqueId.Value,
+ Level = dto.Level,
+ Name = dto.Text,
+ NodeObjectTypeId = dto.NodeObjectType.Value,
+ ParentId = dto.ParentId,
+ Path = dto.Path,
+ SortOrder = dto.SortOrder,
+ HasChildren = false,
+ IsPublished = false
+ };
+ return entity;
+ }
+
+ public NodeDto BuildDto(UmbracoEntity entity)
+ {
+ var node = new NodeDto
+ {
+ CreateDate = entity.CreateDate,
+ Level = short.Parse(entity.Level.ToString(CultureInfo.InvariantCulture)),
+ NodeId = entity.Id,
+ NodeObjectType = entity.NodeObjectTypeId,
+ ParentId = entity.ParentId,
+ Path = entity.Path,
+ SortOrder = entity.SortOrder,
+ Text = entity.Name,
+ Trashed = entity.Trashed,
+ UniqueId = entity.Key,
+ UserId = entity.CreatorId
+ };
+ return node;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
new file mode 100644
index 0000000000..62d2978004
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs
@@ -0,0 +1,177 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Umbraco.Core.Models.EntityBase;
+using Umbraco.Core.Models.Rdbms;
+using Umbraco.Core.Persistence.Factories;
+using Umbraco.Core.Persistence.Querying;
+using Umbraco.Core.Persistence.UnitOfWork;
+
+namespace Umbraco.Core.Persistence.Repositories
+{
+ ///
+ /// Represents the EntityRepository used to query objects.
+ ///
+ ///
+ /// This is limited to objects that are based in the umbracoNode-table.
+ ///
+ internal class EntityRepository : DisposableObject, IEntityRepository
+ {
+ private readonly IDatabaseUnitOfWork _work;
+
+ public EntityRepository(IDatabaseUnitOfWork work)
+ {
+ _work = work;
+ }
+
+ ///
+ /// Returns the Unit of Work added to the repository
+ ///
+ protected internal IDatabaseUnitOfWork UnitOfWork
+ {
+ get { return _work; }
+ }
+
+ ///
+ /// Internal for testing purposes
+ ///
+ internal Guid UnitKey
+ {
+ get { return (Guid)_work.Key; }
+ }
+
+ #region Query Methods
+
+ public virtual IUmbracoEntity Get(int id)
+ {
+ var sql = GetBaseWhere(id);
+ var nodeDto = _work.Database.FirstOrDefault(sql);
+ if (nodeDto == null)
+ return null;
+
+ var factory = new UmbracoEntityFactory();
+ var entity = factory.BuildEntity(nodeDto);
+
+ //TODO Update HasChildren and IsPublished
+
+ return entity;
+ }
+
+ public virtual IUmbracoEntity Get(int id, Guid objectTypeId)
+ {
+ var sql = GetBaseWhere(objectTypeId, id);
+ var nodeDto = _work.Database.FirstOrDefault(sql);
+ if (nodeDto == null)
+ return null;
+
+ var factory = new UmbracoEntityFactory();
+ var entity = factory.BuildEntity(nodeDto);
+
+ //TODO Update HasChildren and IsPublished
+
+ return entity;
+ }
+
+ public virtual IEnumerable GetAll(Guid objectTypeId, params int[] ids)
+ {
+ if (ids.Any())
+ {
+ foreach (var id in ids)
+ {
+ yield return Get(id, objectTypeId);
+ }
+ }
+ else
+ {
+ var sql = GetBaseWhere(objectTypeId);
+ var dtos = _work.Database.Fetch(sql);
+
+ var factory = new UmbracoEntityFactory();
+
+ foreach (var dto in dtos)
+ {
+ var entity = factory.BuildEntity(dto);
+ //TODO Update HasChildren and IsPublished properties
+ yield return entity;
+ }
+ }
+ }
+
+ public virtual IEnumerable GetByQuery(IQuery query)
+ {
+ var sqlClause = GetBaseQuery();
+ var translator = new SqlTranslator(sqlClause, query);
+ var sql = translator.Translate();
+
+ var dtos = _work.Database.Fetch(sql);
+
+ var factory = new UmbracoEntityFactory();
+ var list = dtos.Select(factory.BuildEntity).Cast().ToList();
+
+ //TODO Update HasChildren and IsPublished properties
+
+ return list;
+ }
+
+ public virtual IEnumerable GetByQuery(IQuery query, Guid objectTypeId)
+ {
+ var sqlClause = GetBaseWhere(objectTypeId);
+ var translator = new SqlTranslator(sqlClause, query);
+ var sql = translator.Translate();
+
+ var dtos = _work.Database.Fetch(sql);
+
+ var factory = new UmbracoEntityFactory();
+ var list = dtos.Select(factory.BuildEntity).Cast().ToList();
+
+ //TODO Update HasChildren and IsPublished properties
+
+ return list;
+ }
+
+ #endregion
+
+ #region Sql Statements
+
+ protected virtual Sql GetBaseQuery()
+ {
+ var sql = new Sql()
+ .From();
+ return sql;
+ }
+
+ protected virtual Sql GetBaseWhere(Guid id)
+ {
+ var sql = GetBaseQuery()
+ .Where(x => x.NodeObjectType == id);
+ return sql;
+ }
+
+ protected virtual Sql GetBaseWhere(int id)
+ {
+ var sql = GetBaseQuery()
+ .Where(x => x.NodeId == id);
+ return sql;
+ }
+
+ protected virtual Sql GetBaseWhere(Guid objectId, int id)
+ {
+ var sql = GetBaseWhere(objectId)
+ .Where(x => x.NodeId == id);
+ return sql;
+ }
+
+ #endregion
+
+ ///
+ /// Dispose disposable properties
+ ///
+ ///
+ /// Ensure the unit of work is disposed
+ ///
+ protected override void DisposeResources()
+ {
+ UnitOfWork.DisposeIfDisposable();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IEntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IEntityRepository.cs
new file mode 100644
index 0000000000..6df0293be0
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IEntityRepository.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using Umbraco.Core.Models.EntityBase;
+using Umbraco.Core.Persistence.Querying;
+
+namespace Umbraco.Core.Persistence.Repositories
+{
+ public interface IEntityRepository : IRepository
+ {
+ IUmbracoEntity Get(int id);
+ IUmbracoEntity Get(int id, Guid objectTypeId);
+ IEnumerable GetAll(Guid objectTypeId, params int[] ids);
+ IEnumerable GetByQuery(IQuery query);
+ IEnumerable GetByQuery(IQuery query, Guid objectTypeId);
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/RepositoryFactory.cs b/src/Umbraco.Core/Persistence/RepositoryFactory.cs
index aac31b9568..78007f35da 100644
--- a/src/Umbraco.Core/Persistence/RepositoryFactory.cs
+++ b/src/Umbraco.Core/Persistence/RepositoryFactory.cs
@@ -32,6 +32,11 @@ namespace Umbraco.Core.Persistence
CreateUserTypeRepository(uow));
}
+ internal virtual IEntityRepository CreateEntityRepository(IDatabaseUnitOfWork uow)
+ {
+ return new EntityRepository(uow);
+ }
+
public virtual IContentRepository CreateContentRepository(IDatabaseUnitOfWork uow)
{
return new ContentRepository(
diff --git a/src/Umbraco.Core/Services/EntityService.cs b/src/Umbraco.Core/Services/EntityService.cs
new file mode 100644
index 0000000000..42f7bcb189
--- /dev/null
+++ b/src/Umbraco.Core/Services/EntityService.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using Umbraco.Core.Models;
+using Umbraco.Core.Models.EntityBase;
+using Umbraco.Core.Persistence;
+using Umbraco.Core.Persistence.UnitOfWork;
+
+namespace Umbraco.Core.Services
+{
+ internal class EntityService : IService
+ {
+ private readonly IDatabaseUnitOfWorkProvider _uowProvider;
+ private readonly RepositoryFactory _repositoryFactory;
+
+ public EntityService()
+ : this(new RepositoryFactory())
+ { }
+
+ public EntityService(RepositoryFactory repositoryFactory)
+ : this(new PetaPocoUnitOfWorkProvider(), repositoryFactory)
+ { }
+
+ public EntityService(IDatabaseUnitOfWorkProvider provider)
+ : this(provider, new RepositoryFactory())
+ { }
+
+ public EntityService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory)
+ {
+ _uowProvider = provider;
+ _repositoryFactory = repositoryFactory;
+ }
+
+ ///
+ /// Gets an UmbracoEntity by its Id, and optionally loads the complete object graph.
+ ///
+ ///
+ /// By default this will load the base type with a minimum set of properties.
+ ///
+ /// Id of the object to retrieve
+ /// Optional bool to load the complete object graph when set to False.
+ /// An
+ public virtual IUmbracoEntity Get(int id, bool loadBaseType = true)
+ {
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// Gets an UmbracoEntity by its Id and specified Type. Optionally loads the complete object graph.
+ ///
+ ///
+ /// By default this will load the base type with a minimum set of properties.
+ ///
+ /// Type of the model to retrieve. Must be based on an
+ /// Id of the object to retrieve
+ /// Optional bool to load the complete object graph when set to False.
+ /// An
+ public virtual IUmbracoEntity Get(int id, bool loadBaseType = true) where T : IUmbracoEntity
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual IUmbracoEntity GetParent(int id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual IEnumerable GetChildren(int id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual IEnumerable GetDescendents(int id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual IEnumerable GetAll() where T : IUmbracoEntity
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual IEnumerable GetAll(UmbracoObjectTypes objectType)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual IEnumerable GetAll(Guid objectTypeId)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual UmbracoObjectTypes GetObjectType(int id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual UmbracoObjectTypes GetObjectType(IUmbracoEntity entity)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Type GetModelType(int id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual Type GetModelType(UmbracoObjectTypes objectType)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 1b4eab601a..c8ad3e9626 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -109,6 +109,8 @@
+
+
@@ -206,6 +208,9 @@
+
+
+
@@ -213,6 +218,7 @@
+
@@ -436,7 +442,9 @@
+
+
@@ -670,6 +678,7 @@
+