using System;
using System.Collections.Generic;
using System.Reflection;
using Abp.Extensions;
namespace Abp.Domain.Entities
{
///
/// A shortcut of for most used primary key type ().
///
[Serializable]
public abstract class Entity : Entity, IEntity
{
}
///
/// Basic implementation of IEntity interface.
/// An entity can inherit this class of directly implement to IEntity interface.
///
/// Type of the primary key of the entity
[Serializable]
public abstract class Entity : IEntity
{
///
/// Unique identifier for this entity.
///
public virtual TPrimaryKey Id { get; set; }
///
/// Checks if this entity is transient (it has not an Id).
///
/// True, if this entity is transient
public virtual bool IsTransient()
{
if (EqualityComparer.Default.Equals(Id, default(TPrimaryKey)))
{
return true;
}
//Workaround for EF Core since it sets int/long to min value when attaching to dbcontext
if (typeof(TPrimaryKey) == typeof(int))
{
return Convert.ToInt32(Id) <= 0;
}
if (typeof(TPrimaryKey) == typeof(long))
{
return Convert.ToInt64(Id) <= 0;
}
return false;
}
///
public override bool Equals(object obj)
{
if (obj == null || !(obj is Entity))
{
return false;
}
//Same instances must be considered as equal
if (ReferenceEquals(this, obj))
{
return true;
}
//Transient objects are not considered as equal
var other = (Entity)obj;
if (IsTransient() && other.IsTransient())
{
return false;
}
//Must have a IS-A relation of types or must be same type
var typeOfThis = GetType();
var typeOfOther = other.GetType();
if (!typeOfThis.GetTypeInfo().IsAssignableFrom(typeOfOther) && !typeOfOther.GetTypeInfo().IsAssignableFrom(typeOfThis))
{
return false;
}
if (this is IMayHaveTenant && other is IMayHaveTenant &&
this.As().TenantId != other.As().TenantId)
{
return false;
}
if (this is IMustHaveTenant && other is IMustHaveTenant &&
this.As().TenantId != other.As().TenantId)
{
return false;
}
return Id.Equals(other.Id);
}
///
public override int GetHashCode()
{
if (Id == null)
{
return 0;
}
return Id.GetHashCode();
}
///
public static bool operator ==(Entity left, Entity right)
{
if (Equals(left, null))
{
return Equals(right, null);
}
return left.Equals(right);
}
///
public static bool operator !=(Entity left, Entity right)
{
return !(left == right);
}
///
public override string ToString()
{
return $"[{GetType().Name} {Id}]";
}
}
}