diff --git a/src/Umbraco.Core/Models/IMemberGroup.cs b/src/Umbraco.Core/Models/IMemberGroup.cs
new file mode 100644
index 0000000000..8454767ef3
--- /dev/null
+++ b/src/Umbraco.Core/Models/IMemberGroup.cs
@@ -0,0 +1,12 @@
+using Umbraco.Core.Models.EntityBase;
+
+namespace Umbraco.Core.Models
+{
+ ///
+ /// Represents a member type
+ ///
+ public interface IMemberGroup : IAggregateRoot
+ {
+ string Name { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/MemberGroup.cs b/src/Umbraco.Core/Models/MemberGroup.cs
new file mode 100644
index 0000000000..8a8b7a72d7
--- /dev/null
+++ b/src/Umbraco.Core/Models/MemberGroup.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Reflection;
+using System.Runtime.Serialization;
+using Umbraco.Core.Models.EntityBase;
+
+namespace Umbraco.Core.Models
+{
+ ///
+ /// Represents a member type
+ ///
+ [Serializable]
+ [DataContract(IsReference = true)]
+ public class MemberGroup : Entity, IMemberGroup
+ {
+ private string _name;
+
+ private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo(x => x.Name);
+
+ [DataMember]
+ public string Name
+ {
+ get { return _name; }
+ set
+ {
+ SetPropertyValueAndDetectChanges(o =>
+ {
+ _name = value;
+ return _name;
+ }, _name, NameSelector);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Factories/MemberGroupFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberGroupFactory.cs
new file mode 100644
index 0000000000..2b87884c9a
--- /dev/null
+++ b/src/Umbraco.Core/Persistence/Factories/MemberGroupFactory.cs
@@ -0,0 +1,64 @@
+using System;
+using Umbraco.Core.Models;
+using Umbraco.Core.Models.Rdbms;
+
+namespace Umbraco.Core.Persistence.Factories
+{
+ internal class MemberGroupFactory : IEntityFactory
+ {
+
+ private readonly Guid _nodeObjectTypeId;
+
+ public MemberGroupFactory()
+ {
+ _nodeObjectTypeId = new Guid(Constants.ObjectTypes.MemberGroup);
+ }
+
+ #region Implementation of IEntityFactory
+
+ public IMemberGroup BuildEntity(NodeDto dto)
+ {
+ var template = new MemberGroup
+ {
+ CreateDate = dto.CreateDate,
+ Id = dto.NodeId,
+ Key = dto.UniqueId.Value,
+ Name = dto.Text
+ };
+
+ //on initial construction we don't want to have dirty properties tracked
+ // http://issues.umbraco.org/issue/U4-1946
+ template.ResetDirtyProperties(false);
+ return template;
+ }
+
+ public NodeDto BuildDto(IMemberGroup entity)
+ {
+ var dto = new NodeDto
+ {
+ CreateDate = entity.CreateDate,
+ NodeId = entity.Id,
+ Level = 0,
+ NodeObjectType = _nodeObjectTypeId,
+ ParentId = -1,
+ Path = "",
+ SortOrder = 0,
+ Text = entity.Name,
+ Trashed = false,
+ UniqueId = entity.Key,
+ UserId = 0
+ };
+
+ if (entity.HasIdentity)
+ {
+ dto.NodeId = entity.Id;
+ dto.Path = "-1," + entity.Id;
+ }
+
+ return dto;
+ }
+
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs
index 182e47eecf..53c26c1321 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs
@@ -1,7 +1,121 @@
-namespace Umbraco.Core.Persistence.Repositories
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Umbraco.Core.Models;
+using Umbraco.Core.Models.EntityBase;
+using Umbraco.Core.Models.Rdbms;
+using Umbraco.Core.Persistence.Caching;
+using Umbraco.Core.Persistence.Factories;
+using Umbraco.Core.Persistence.Querying;
+using Umbraco.Core.Persistence.UnitOfWork;
+
+namespace Umbraco.Core.Persistence.Repositories
{
- public class MemberGroupRepository
+ internal class MemberGroupRepository : PetaPocoRepositoryBase
{
-
+ public MemberGroupRepository(IDatabaseUnitOfWork work) : base(work)
+ {
+ }
+
+ public MemberGroupRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache) : base(work, cache)
+ {
+ }
+
+ private readonly MemberGroupFactory _modelFactory = new MemberGroupFactory();
+
+ protected override IMemberGroup PerformGet(int id)
+ {
+ var sql = GetBaseQuery(false);
+ sql.Where(GetBaseWhereClause(), new { Id = id });
+
+ var dto = Database.Fetch(sql).FirstOrDefault();
+
+ return dto == null ? null : _modelFactory.BuildEntity(dto);
+ }
+
+ protected override IEnumerable PerformGetAll(params int[] ids)
+ {
+ var memberType = new Guid(Constants.ObjectTypes.MemberGroup);
+ if (ids.Any())
+ {
+ var sql = new Sql()
+ .From()
+ .Where(dto => dto.NodeObjectType == memberType)
+ .Where("Name in (@ids)", new {ids = ids});
+ return Database.Fetch(sql)
+ .Select(x => _modelFactory.BuildEntity(x));
+ }
+ else
+ {
+ var sql = new Sql()
+ .From()
+ .Where(dto => dto.NodeObjectType == memberType);
+ return Database.Fetch(sql)
+ .Select(x => _modelFactory.BuildEntity(x));
+ }
+ }
+
+ protected override IEnumerable PerformGetByQuery(IQuery query)
+ {
+ var sqlClause = GetBaseQuery(false);
+ var translator = new SqlTranslator(sqlClause, query);
+ var sql = translator.Translate();
+
+ return Database.Fetch(sql)
+ .Select(x => _modelFactory.BuildEntity(x));
+ }
+
+ protected override Sql GetBaseQuery(bool isCount)
+ {
+ var sql = new Sql();
+ sql.Select(isCount ? "COUNT(*)" : "*")
+ .From()
+ .Where(x => x.NodeObjectType == NodeObjectTypeId);
+ return sql;
+ }
+
+ protected override string GetBaseWhereClause()
+ {
+ return "umbracoNode.id = @Id";
+ }
+
+ protected override IEnumerable GetDeleteClauses()
+ {
+ var list = new[]
+ {
+ "DELETE FROM cmsMember2MemberGroup WHERE MemberGroup = @Id",
+ "DELETE FROM umbracoNode WHERE id = @Id"
+ };
+ return list;
+ }
+
+ protected override Guid NodeObjectTypeId
+ {
+ get { return new Guid(Constants.ObjectTypes.MemberGroup); }
+ }
+
+ protected override void PersistNewItem(IMemberGroup entity)
+ {
+ //Save to db
+ var group = entity as MemberGroup;
+ group.AddingEntity();
+ var dto = _modelFactory.BuildDto(group);
+ var o = Database.IsNew(dto) ? Convert.ToInt32(Database.Insert(dto)) : Database.Update(dto);
+
+ //Update with new correct path
+ dto.Path = string.Concat("-1,", dto.NodeId);
+ Database.Update(dto);
+
+ group.ResetDirtyProperties();
+ }
+
+ protected override void PersistUpdatedItem(IMemberGroup entity)
+ {
+ var dto = _modelFactory.BuildDto(entity);
+
+ Database.Update(dto);
+
+ ((ICanBeDirty)entity).ResetDirtyProperties();
+ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 5bb05c46d3..b9fe5da3bb 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -190,8 +190,10 @@
+
+
@@ -203,6 +205,7 @@
+