Adding additional methods to the MemberRepository to support various types of lookups/queries, and experimenting with adding dummy properties to the model so a strongly typed query can be translated using mappers.
GetByQuery needs to be refactored so the selection is done in a subquery, so we don't loose properties in the result set
This commit is contained in:
@@ -34,6 +34,9 @@ namespace Umbraco.Core.Models.Membership
|
||||
private static readonly PropertyInfo DefaultContentTypeIdSelector = ExpressionHelper.GetPropertyInfo<Member, int>(x => x.ContentTypeId);
|
||||
private static readonly PropertyInfo DefaultContentTypeAliasSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.ContentTypeAlias);
|
||||
|
||||
public Member()
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Integer Id
|
||||
/// </summary>
|
||||
@@ -424,6 +427,16 @@ namespace Umbraco.Core.Models.Membership
|
||||
|
||||
public object ProfileId { get; set; }
|
||||
public IEnumerable<object> Groups { get; set; }
|
||||
|
||||
/* Internal experiment - only used for mapping queries.
|
||||
* Adding these to have first level properties instead of the Properties collection.
|
||||
*/
|
||||
internal string LongStringPropertyValue { get; set; }
|
||||
internal string ShortStringPropertyValue { get; set; }
|
||||
internal int IntegerropertyValue { get; set; }
|
||||
internal bool BoolPropertyValue { get; set; }
|
||||
internal DateTime DateTimePropertyValue { get; set; }
|
||||
internal string PropertyTypeAlias { get; set; }
|
||||
|
||||
#region Internal methods
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
internal abstract class MemberProfile : Profile, IUmbracoEntity
|
||||
internal class MemberProfile : Profile, IUmbracoEntity
|
||||
{
|
||||
private Lazy<int> _parentId;
|
||||
private int _sortOrder;
|
||||
@@ -16,12 +16,12 @@ namespace Umbraco.Core.Models.Membership
|
||||
private bool _trashed;
|
||||
private PropertyCollection _properties;
|
||||
|
||||
private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo<MemberProfile, int>(x => ((IUmbracoEntity)x).ParentId);
|
||||
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<MemberProfile, int>(x => ((IUmbracoEntity)x).SortOrder);
|
||||
private static readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo<MemberProfile, int>(x => ((IUmbracoEntity)x).Level);
|
||||
private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo<MemberProfile, string>(x => ((IUmbracoEntity)x).Path);
|
||||
private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo<MemberProfile, int>(x => ((IUmbracoEntity)x).CreatorId);
|
||||
private static readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo<MemberProfile, bool>(x => x.Trashed);
|
||||
private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo<IUmbracoEntity, int>(x => x.ParentId);
|
||||
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<IUmbracoEntity, int>(x => x.SortOrder);
|
||||
private static readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo<IUmbracoEntity, int>(x => x.Level);
|
||||
private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo<IUmbracoEntity, string>(x => x.Path);
|
||||
private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo<IUmbracoEntity, int>(x => x.CreatorId);
|
||||
private static readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo<Member, bool>(x => x.Trashed);
|
||||
private readonly static PropertyInfo PropertyCollectionSelector = ExpressionHelper.GetPropertyInfo<Member, PropertyCollection>(x => x.Properties);
|
||||
|
||||
protected void PropertiesChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
@@ -29,11 +29,14 @@ namespace Umbraco.Core.Models.Membership
|
||||
OnPropertyChanged(PropertyCollectionSelector);
|
||||
}
|
||||
|
||||
public abstract new int Id { get; set; }
|
||||
public abstract Guid Key { get; set; }
|
||||
public abstract DateTime CreateDate { get; set; }
|
||||
public abstract DateTime UpdateDate { get; set; }
|
||||
public abstract bool HasIdentity { get; protected set; }
|
||||
protected MemberProfile()
|
||||
{}
|
||||
|
||||
public virtual new int Id { get; set; }
|
||||
public virtual Guid Key { get; set; }
|
||||
public virtual DateTime CreateDate { get; set; }
|
||||
public virtual DateTime UpdateDate { get; set; }
|
||||
public virtual bool HasIdentity { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profile of the user who created this Content
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
public IMember BuildEntity(MemberReadOnlyDto dto)
|
||||
{
|
||||
var member = new Member
|
||||
var member = new Member()
|
||||
{
|
||||
Id = dto.NodeId,
|
||||
CreateDate = dto.CreateDate,
|
||||
|
||||
@@ -60,6 +60,14 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
CacheMap<Member, PropertyDataDto>(src => src.LastLockoutDate, dto => dto.Date);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.LastLoginDate, dto => dto.Date);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.LastPasswordChangeDate, dto => dto.Date);
|
||||
|
||||
/* Internal experiment */
|
||||
CacheMap<Member, PropertyDataDto>(src => src.DateTimePropertyValue, dto => dto.Date);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.IntegerropertyValue, dto => dto.Integer);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.BoolPropertyValue, dto => dto.Integer);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.LongStringPropertyValue, dto => dto.Text);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.ShortStringPropertyValue, dto => dto.VarChar);
|
||||
CacheMap<Member, PropertyTypeDto>(src => src.PropertyTypeAlias, dto => dto.Alias);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -250,7 +250,7 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
case "EndsWith":
|
||||
return string.Format("upper({0}) like '%{1}'", r, RemoveQuote(args[0].ToString()).ToUpper());
|
||||
case "Contains":
|
||||
return string.Format("upper({0}) like '%{1}%'", r, RemoveQuote(args[0].ToString()).ToUpper());
|
||||
return string.Format("{0} like '%{1}%'", r, RemoveQuote(args[0].ToString()).ToUpper());
|
||||
case "Substring":
|
||||
var startIndex = Int32.Parse(args[0].ToString()) + 1;
|
||||
if (args.Count == 2)
|
||||
|
||||
@@ -25,10 +25,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
* GetById - get a member by its integer Id
|
||||
* GetByKey - get a member by its unique guid Id (which should correspond to a membership provider user's id)
|
||||
* GetByUsername - get a member by its username
|
||||
*
|
||||
* GetByPropertyValue - get members with a certain property value (supply both property alias and value?)
|
||||
* GetByMemberTypeAlias - get all members of a certain type
|
||||
* GetByMemberGroup - get all members in a specific group
|
||||
* GetAllMembers
|
||||
*/
|
||||
|
||||
#region Overrides of RepositoryBase<int, IMembershipUser>
|
||||
@@ -43,23 +43,39 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
|
||||
new PropertyDataRelator().Map, sql);
|
||||
|
||||
if (dto == null || dto.Any() == false)
|
||||
return null;
|
||||
|
||||
var factory = new MemberReadOnlyFactory();
|
||||
var member = factory.BuildEntity(dto.First());
|
||||
|
||||
return member;
|
||||
return BuildFromDto(dto);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IMember> PerformGetAll(params int[] ids)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var sql = GetBaseQuery(false);
|
||||
if (ids.Any())
|
||||
{
|
||||
var statement = string.Join(" OR ", ids.Select(x => string.Format("umbracoNode.id='{0}'", x)));
|
||||
sql.Where(statement);
|
||||
}
|
||||
sql.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
var dtos =
|
||||
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
|
||||
new PropertyDataRelator().Map, sql);
|
||||
|
||||
return BuildFromDtos(dtos);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IMember> PerformGetByQuery(IQuery<IMember> query)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var sqlClause = GetBaseQuery(false);
|
||||
var translator = new SqlTranslator<IMember>(sqlClause, query);
|
||||
var sql = translator.Translate()
|
||||
.OrderByDescending<ContentVersionDto>(x => x.VersionDate)
|
||||
.OrderBy<NodeDto>(x => x.SortOrder);
|
||||
|
||||
var dtos =
|
||||
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
|
||||
new PropertyDataRelator().Map, sql);
|
||||
|
||||
return BuildFromDtos(dtos);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -68,7 +84,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override Sql GetBaseQuery(bool isCount)
|
||||
{
|
||||
//TODO Count
|
||||
if (isCount)
|
||||
{
|
||||
var sqlCount = new Sql()
|
||||
.Select("COUNT(*)")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<ContentDto>().On<ContentDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
||||
.InnerJoin<ContentTypeDto>().On<ContentTypeDto, ContentDto>(left => left.NodeId, right => right.ContentTypeId)
|
||||
.InnerJoin<ContentVersionDto>().On<ContentVersionDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
||||
.InnerJoin<MemberDto>().On<MemberDto, ContentDto>(left => left.NodeId, right => right.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
|
||||
return sqlCount;
|
||||
}
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("umbracoNode.*", "cmsContent.contentType", "cmsContentType.alias AS ContentTypeAlias", "cmsContentVersion.VersionId",
|
||||
"cmsContentVersion.VersionDate", "cmsContentVersion.LanguageLocale", "cmsMember.Email",
|
||||
@@ -98,7 +126,21 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override IEnumerable<string> GetDeleteClauses()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var list = new List<string>
|
||||
{
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE parentId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE childId = @Id",
|
||||
"DELETE FROM cmsTagRelationship WHERE nodeId = @Id",
|
||||
"DELETE FROM cmsPropertyData WHERE contentNodeId = @Id",
|
||||
"DELETE FROM cmsMember WHERE nodeId = @Id",
|
||||
"DELETE FROM cmsContentVersion WHERE ContentId = @Id",
|
||||
"DELETE FROM cmsContentXml WHERE nodeID = @Id",
|
||||
"DELETE FROM cmsContent WHERE NodeId = @Id",
|
||||
"DELETE FROM umbracoNode WHERE id = @Id"
|
||||
};
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override Guid NodeObjectTypeId
|
||||
@@ -135,5 +177,91 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
//NOTE Might be sufficient to use the GetByQuery method for this, as the mapping should cover it
|
||||
public IMember GetByKey(Guid key)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
sql.Where<NodeDto>(x => x.UniqueId == key);
|
||||
sql.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
var dto =
|
||||
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
|
||||
new PropertyDataRelator().Map, sql);
|
||||
|
||||
return BuildFromDto(dto);
|
||||
}
|
||||
|
||||
//NOTE Might be sufficient to use the GetByQuery method for this, as the mapping should cover it
|
||||
public IMember GetByUsername(string username)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
sql.Where<MemberDto>(x => x.LoginName == username);
|
||||
sql.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
var dto =
|
||||
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
|
||||
new PropertyDataRelator().Map, sql);
|
||||
|
||||
return BuildFromDto(dto);
|
||||
}
|
||||
|
||||
//NOTE Might be sufficient to use the GetByQuery method for this, as the mapping should cover it
|
||||
public IEnumerable<IMember> GetByMemberTypeAlias(string memberTypeAlias)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
sql.Where<ContentTypeDto>(x => x.Alias == memberTypeAlias);
|
||||
sql.OrderByDescending<ContentVersionDto>(x => x.VersionDate);
|
||||
|
||||
var dtos =
|
||||
Database.Fetch<MemberReadOnlyDto, PropertyDataReadOnlyDto, MemberReadOnlyDto>(
|
||||
new PropertyDataRelator().Map, sql);
|
||||
|
||||
return BuildFromDtos(dtos);
|
||||
}
|
||||
|
||||
/*public IEnumerable<IMember> GetByPropertyValue(string value)
|
||||
{}
|
||||
|
||||
public IEnumerable<IMember> GetByPropertyValue(bool value)
|
||||
{ }
|
||||
|
||||
public IEnumerable<IMember> GetByPropertyValue(int value)
|
||||
{ }
|
||||
|
||||
public IEnumerable<IMember> GetByPropertyValue(DateTime value)
|
||||
{ }
|
||||
|
||||
public IEnumerable<IMember> GetByPropertyValue(string propertyTypeAlias, string value)
|
||||
{ }
|
||||
|
||||
public IEnumerable<IMember> GetByPropertyValue(string propertyTypeAlias, bool value)
|
||||
{ }
|
||||
|
||||
public IEnumerable<IMember> GetByPropertyValue(string propertyTypeAlias, int value)
|
||||
{ }
|
||||
|
||||
public IEnumerable<IMember> GetByPropertyValue(string propertyTypeAlias, DateTime value)
|
||||
{ }*/
|
||||
|
||||
private IMember BuildFromDto(List<MemberReadOnlyDto> dtos)
|
||||
{
|
||||
if (dtos == null || dtos.Any() == false)
|
||||
return null;
|
||||
|
||||
var factory = new MemberReadOnlyFactory();
|
||||
var member = factory.BuildEntity(dtos.First());
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
private IEnumerable<IMember> BuildFromDtos(List<MemberReadOnlyDto> dtos)
|
||||
{
|
||||
if (dtos == null || dtos.Any() == false)
|
||||
return Enumerable.Empty<IMember>();
|
||||
|
||||
var factory = new MemberReadOnlyFactory();
|
||||
return dtos.Select(factory.BuildEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user