updates especially when deleting one since we require all sorts of Ids from the object but the object will be deleted by the time the request reaches other servers so instead we create a json payload to send to other servers which contains all information necessary to refresh/clear the cache on the other servers. This will probably be the preferred way going forward to handle cache refreshing. With this in place, when removing a conent type cache is removed based on events. This also adds a 'class' generic argument constraint to the repository base classes to guarantee we can do null checks and then we also fix a null check on RepositoryBase. Updates the Entity class to properly support tracking properties - this now allows us to determine if an entity was new, which is now used to ensure we don't re-update all of the content cache when a new content type is created. Have also changed the deletion and creation of document types to use the new API, this allows for a lot less processing and streamlining how all cache is invalidated. Fixes the construction of a new Template and Content Type in the v6 api and ensures that default values are set - #U4-1972, #U4-1971
221 lines
6.4 KiB
C#
221 lines
6.4 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Reflection;
|
|
using System.Runtime.Serialization;
|
|
|
|
namespace Umbraco.Core.Models.EntityBase
|
|
{
|
|
/// <summary>
|
|
/// Base Abstract Entity
|
|
/// </summary>
|
|
[Serializable]
|
|
[DataContract(IsReference = true)]
|
|
[DebuggerDisplay("Id: {Id}")]
|
|
public abstract class Entity : TracksChangesEntityBase, IEntity, IRememberBeingDirty, ICanBeDirty
|
|
{
|
|
private bool _hasIdentity;
|
|
private int? _hash;
|
|
private int _id;
|
|
private Guid _key;
|
|
private DateTime _createDate;
|
|
private DateTime _updateDate;
|
|
|
|
private static readonly PropertyInfo IdSelector = ExpressionHelper.GetPropertyInfo<Entity, int>(x => x.Id);
|
|
private static readonly PropertyInfo KeySelector = ExpressionHelper.GetPropertyInfo<Entity, Guid>(x => x.Key);
|
|
private static readonly PropertyInfo CreateDateSelector = ExpressionHelper.GetPropertyInfo<Entity, DateTime>(x => x.CreateDate);
|
|
private static readonly PropertyInfo UpdateDateSelector = ExpressionHelper.GetPropertyInfo<Entity, DateTime>(x => x.UpdateDate);
|
|
private static readonly PropertyInfo HasIdentitySelector = ExpressionHelper.GetPropertyInfo<Entity, bool>(x => x.HasIdentity);
|
|
|
|
|
|
/// <summary>
|
|
/// Integer Id
|
|
/// </summary>
|
|
[DataMember]
|
|
public int Id
|
|
{
|
|
get
|
|
{
|
|
return _id;
|
|
}
|
|
set
|
|
{
|
|
SetPropertyValueAndDetectChanges(o =>
|
|
{
|
|
_id = value;
|
|
HasIdentity = true; //set the has Identity
|
|
return _id;
|
|
}, _id, IdSelector);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Guid based Id
|
|
/// </summary>
|
|
/// <remarks>The key is currectly used to store the Unique Id from the
|
|
/// umbracoNode table, which many of the entities are based on.</remarks>
|
|
[DataMember]
|
|
public Guid Key
|
|
{
|
|
get
|
|
{
|
|
if (_key == Guid.Empty)
|
|
return _id.ToGuid();
|
|
|
|
return _key;
|
|
}
|
|
set
|
|
{
|
|
SetPropertyValueAndDetectChanges(o =>
|
|
{
|
|
_key = value;
|
|
return _key;
|
|
}, _key, KeySelector);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the Created Date
|
|
/// </summary>
|
|
[DataMember]
|
|
public DateTime CreateDate
|
|
{
|
|
get { return _createDate; }
|
|
set
|
|
{
|
|
SetPropertyValueAndDetectChanges(o =>
|
|
{
|
|
_createDate = value;
|
|
return _createDate;
|
|
}, _createDate, CreateDateSelector);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the Modified Date
|
|
/// </summary>
|
|
[DataMember]
|
|
public DateTime UpdateDate
|
|
{
|
|
get { return _updateDate; }
|
|
set
|
|
{
|
|
SetPropertyValueAndDetectChanges(o =>
|
|
{
|
|
_updateDate = value;
|
|
return _updateDate;
|
|
}, _updateDate, UpdateDateSelector);
|
|
}
|
|
}
|
|
|
|
internal virtual void ResetIdentity()
|
|
{
|
|
_hasIdentity = false;
|
|
_id = default(int);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method to call on entity saved when first added
|
|
/// </summary>
|
|
internal virtual void AddingEntity()
|
|
{
|
|
CreateDate = DateTime.Now;
|
|
UpdateDate = DateTime.Now;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method to call on entity saved/updated
|
|
/// </summary>
|
|
internal virtual void UpdatingEntity()
|
|
{
|
|
UpdateDate = DateTime.Now;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indicates whether the current entity has an identity, eg. Id.
|
|
/// </summary>
|
|
public virtual bool HasIdentity
|
|
{
|
|
get
|
|
{
|
|
return _hasIdentity;
|
|
}
|
|
protected set
|
|
{
|
|
SetPropertyValueAndDetectChanges(o =>
|
|
{
|
|
_hasIdentity = value;
|
|
return _hasIdentity;
|
|
}, _hasIdentity, HasIdentitySelector);
|
|
}
|
|
}
|
|
|
|
public static bool operator ==(Entity left, Entity right)
|
|
{
|
|
if (ReferenceEquals(null, left))
|
|
return false;
|
|
|
|
return left.Equals(right);
|
|
}
|
|
|
|
public static bool operator !=(Entity left, Entity right)
|
|
{
|
|
return !(left == right);
|
|
}
|
|
|
|
public virtual bool SameIdentityAs(IEntity other)
|
|
{
|
|
if (ReferenceEquals(null, other))
|
|
return false;
|
|
if (ReferenceEquals(this, other))
|
|
return true;
|
|
|
|
return SameIdentityAs(other as Entity);
|
|
}
|
|
|
|
public virtual bool Equals(Entity other)
|
|
{
|
|
if (ReferenceEquals(null, other))
|
|
return false;
|
|
if (ReferenceEquals(this, other))
|
|
return true;
|
|
|
|
return SameIdentityAs(other);
|
|
}
|
|
|
|
public virtual Type GetRealType()
|
|
{
|
|
return GetType();
|
|
}
|
|
|
|
public virtual bool SameIdentityAs(Entity other)
|
|
{
|
|
if (ReferenceEquals(null, other))
|
|
return false;
|
|
|
|
if (ReferenceEquals(this, other))
|
|
return true;
|
|
|
|
if (GetType() == other.GetRealType() && HasIdentity && other.HasIdentity)
|
|
return other.Id.Equals(Id);
|
|
|
|
return false;
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (ReferenceEquals(null, obj))
|
|
return false;
|
|
if (ReferenceEquals(this, obj))
|
|
return true;
|
|
|
|
return SameIdentityAs(obj as IEntity);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
if (!_hash.HasValue)
|
|
_hash = !HasIdentity ? new int?(base.GetHashCode()) : new int?(Id.GetHashCode() * 397 ^ GetType().GetHashCode());
|
|
return _hash.Value;
|
|
}
|
|
}
|
|
} |