Fixes #U4-5529 properly. Reverts changes to RepositoryBase and alters queries instead. The check for Mandate.That(contentTypeIds.Any() was wrong when trying to select all conent types.
Maybe there's a better fix than this, feel free to update.
This commit is contained in:
@@ -764,7 +764,6 @@ AND umbracoNode.id <> @id",
|
||||
out IDictionary<int, IEnumerable<AssociatedTemplate>> associatedTemplates,
|
||||
out IDictionary<int, IEnumerable<int>> parentContentTypeIds)
|
||||
{
|
||||
Mandate.That(contentTypeIds.Any(), () => new InvalidOperationException("must be at least one content type id specified"));
|
||||
Mandate.ParameterNotNull(db, "db");
|
||||
|
||||
//ensure they are unique
|
||||
@@ -799,8 +798,9 @@ AND umbracoNode.id <> @id",
|
||||
ON Template.nodeId = cmsDocumentType.templateNodeId
|
||||
LEFT JOIN cmsContentType2ContentType as ParentTypes
|
||||
ON ParentTypes.childContentTypeId = cmsContentType.nodeId
|
||||
WHERE (umbracoNode.nodeObjectType = @nodeObjectType)
|
||||
AND (umbracoNode.id IN (@contentTypeIds))";
|
||||
WHERE (umbracoNode.nodeObjectType = @nodeObjectType)";
|
||||
if(contentTypeIds.Any())
|
||||
sql = sql + " AND (umbracoNode.id IN (@contentTypeIds))";
|
||||
|
||||
//NOTE: we are going to assume there's not going to be more than 2100 content type ids since that is the max SQL param count!
|
||||
if ((contentTypeIds.Length - 1) > 2000)
|
||||
@@ -969,10 +969,12 @@ AND umbracoNode.id <> @id",
|
||||
INNER JOIN cmsDataType as DT
|
||||
ON PT.dataTypeId = DT.[nodeId]
|
||||
LEFT JOIN cmsPropertyTypeGroup as PG
|
||||
ON PG.[id] = PT.propertyTypeGroupId
|
||||
WHERE (PT.contentTypeId in (@contentTypeIds))
|
||||
ON PG.[id] = PT.propertyTypeGroupId";
|
||||
|
||||
ORDER BY (PG.id)";
|
||||
if(contentTypeIds.Any())
|
||||
sql = sql + " WHERE (PT.contentTypeId in (@contentTypeIds))";
|
||||
|
||||
sql = sql + " ORDER BY (PG.id)";
|
||||
|
||||
//NOTE: we are going to assume there's not going to be more than 2100 content type ids since that is the max SQL param count!
|
||||
// Since there are 2 groups of params, it will be half!
|
||||
|
||||
@@ -14,29 +14,29 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">Type of <see cref="IAggregateRoot"/> entity for which the repository is used</typeparam>
|
||||
/// <typeparam name="TId">Type of the Id used for this entity</typeparam>
|
||||
internal abstract class RepositoryBase<TId, TEntity> : DisposableObject, IRepositoryQueryable<TId, TEntity>, IUnitOfWorkRepository
|
||||
where TEntity : class, IAggregateRoot
|
||||
internal abstract class RepositoryBase<TId, TEntity> : DisposableObject, IRepositoryQueryable<TId, TEntity>, IUnitOfWorkRepository
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly IUnitOfWork _work;
|
||||
private readonly IUnitOfWork _work;
|
||||
private readonly IRepositoryCacheProvider _cache;
|
||||
|
||||
protected RepositoryBase(IUnitOfWork work)
|
||||
protected RepositoryBase(IUnitOfWork work)
|
||||
: this(work, RuntimeCacheProvider.Current)
|
||||
{
|
||||
}
|
||||
|
||||
internal RepositoryBase(IUnitOfWork work, IRepositoryCacheProvider cache)
|
||||
internal RepositoryBase(IUnitOfWork work, IRepositoryCacheProvider cache)
|
||||
{
|
||||
if (work == null) throw new ArgumentNullException("work");
|
||||
if (cache == null) throw new ArgumentNullException("cache");
|
||||
_work = work;
|
||||
if (work == null) throw new ArgumentNullException("work");
|
||||
if (cache == null) throw new ArgumentNullException("cache");
|
||||
_work = work;
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Unit of Work added to the repository
|
||||
/// </summary>
|
||||
protected internal IUnitOfWork UnitOfWork
|
||||
protected internal IUnitOfWork UnitOfWork
|
||||
{
|
||||
get { return _work; }
|
||||
}
|
||||
@@ -74,7 +74,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="entity"></param>
|
||||
public virtual void Delete(TEntity entity)
|
||||
{
|
||||
if(_work != null)
|
||||
if (_work != null)
|
||||
{
|
||||
_work.RegisterRemoved(entity, this);
|
||||
}
|
||||
@@ -110,7 +110,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
asEntity.ResetDirtyProperties(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -120,10 +120,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var rEntity = _cache.GetById(typeof(TEntity), key);
|
||||
if (rEntity != null)
|
||||
{
|
||||
return Attempt.Succeed((TEntity) rEntity);
|
||||
return Attempt.Succeed((TEntity)rEntity);
|
||||
}
|
||||
return Attempt<TEntity>.Fail();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<TEntity> PerformGetAll(params TId[] ids);
|
||||
/// <summary>
|
||||
@@ -133,56 +133,61 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns></returns>
|
||||
public IEnumerable<TEntity> GetAll(params TId[] ids)
|
||||
{
|
||||
//ensure they are de-duplicated, easy win if people don't do this as this can cause many excess queries
|
||||
ids = ids.Distinct()
|
||||
//don't query by anything that is a default of T (like a zero)
|
||||
//TODO: I think we should enabled this in case accidental calls are made to get all with invalid ids
|
||||
//.Where(x => Equals(x, default(TId)) == false)
|
||||
.ToArray();
|
||||
|
||||
if (ids.Length > 2000)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot perform a query with more than 2000 parameters");
|
||||
}
|
||||
|
||||
TEntity[] entityCollection = {};
|
||||
|
||||
if (ids.Any())
|
||||
{
|
||||
var entities = _cache.GetByIds(
|
||||
typeof (TEntity), ids.Select(id => id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString())).ToList())
|
||||
typeof(TEntity), ids.Select(id => id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString())).ToList())
|
||||
.ToArray();
|
||||
|
||||
if (ids.Count().Equals(entities.Count()) && entities.Any(x => x == null) == false)
|
||||
return entities.Select(x => (TEntity)x);
|
||||
|
||||
if (ids.Any())
|
||||
{
|
||||
entityCollection = PerformGetAll(ids)
|
||||
//ensure we don't include any null refs in the returned collection!
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
|
||||
//We need to put a threshold here! IF there's an insane amount of items
|
||||
// coming back here we don't want to chuck it all into memory, this added cache here
|
||||
// is more for convenience when paging stuff temporarily
|
||||
|
||||
if (entityCollection.Length > 100) return entityCollection;
|
||||
|
||||
foreach (var entity in entityCollection.Where(entity => entity != null))
|
||||
{
|
||||
_cache.Save(typeof(TEntity), entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var allEntities = _cache.GetAllByType(typeof (TEntity)).ToArray();
|
||||
|
||||
var allEntities = _cache.GetAllByType(typeof(TEntity)).ToArray();
|
||||
|
||||
if (allEntities.Any())
|
||||
{
|
||||
//Get count of all entities of current type (TEntity) to ensure cached result is correct
|
||||
var query = Query<TEntity>.Builder.Where(x => x.Id != 0);
|
||||
int totalCount = PerformCount(query);
|
||||
|
||||
if(allEntities.Count() == totalCount)
|
||||
if (allEntities.Count() == totalCount)
|
||||
return allEntities.Select(x => (TEntity)x);
|
||||
}
|
||||
}
|
||||
|
||||
var entityCollection = PerformGetAll(ids)
|
||||
//ensure we don't include any null refs in the returned collection!
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
|
||||
//We need to put a threshold here! IF there's an insane amount of items
|
||||
// coming back here we don't want to chuck it all into memory, this added cache here
|
||||
// is more for convenience when paging stuff temporarily
|
||||
|
||||
if (entityCollection.Length > 100) return entityCollection;
|
||||
|
||||
foreach (var entity in entityCollection)
|
||||
{
|
||||
if (entity != null)
|
||||
{
|
||||
_cache.Save(typeof(TEntity), entity);
|
||||
}
|
||||
}
|
||||
|
||||
return entityCollection;
|
||||
}
|
||||
|
||||
@@ -212,7 +217,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return PerformExists(id);
|
||||
return PerformExists(id);
|
||||
}
|
||||
|
||||
protected abstract int PerformCount(IQuery<TEntity> query);
|
||||
@@ -224,7 +229,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
public int Count(IQuery<TEntity> query)
|
||||
{
|
||||
return PerformCount(query);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -245,10 +250,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
//if an exception is thrown we need to remove the entry from cache, this is ONLY a work around because of the way
|
||||
// that we cache entities: http://issues.umbraco.org/issue/U4-4259
|
||||
_cache.Delete(typeof (TEntity), entity);
|
||||
_cache.Delete(typeof(TEntity), entity);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -266,10 +271,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
//if an exception is thrown we need to remove the entry from cache, this is ONLY a work around because of the way
|
||||
// that we cache entities: http://issues.umbraco.org/issue/U4-4259
|
||||
_cache.Delete(typeof (TEntity), entity);
|
||||
_cache.Delete(typeof(TEntity), entity);
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -304,7 +309,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
protected virtual Guid ConvertIdToGuid(TId id)
|
||||
{
|
||||
int i = 0;
|
||||
if(int.TryParse(id.ToString(), out i))
|
||||
if (int.TryParse(id.ToString(), out i))
|
||||
{
|
||||
return i.ToGuid();
|
||||
}
|
||||
@@ -316,15 +321,15 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return id.EncodeAsGuid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose disposable properties
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Ensure the unit of work is disposed
|
||||
/// </remarks>
|
||||
protected override void DisposeResources()
|
||||
{
|
||||
UnitOfWork.DisposeIfDisposable();
|
||||
}
|
||||
/// <summary>
|
||||
/// Dispose disposable properties
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Ensure the unit of work is disposed
|
||||
/// </remarks>
|
||||
protected override void DisposeResources()
|
||||
{
|
||||
UnitOfWork.DisposeIfDisposable();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user