Abp-Entity


看下源码:

namespace Abp.Domain.Entities
{
    /// 
    /// A shortcut of  for most used primary key type ().
    /// 
    [Serializable]
    public abstract class Entity : Entity<int>, 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 virtual bool EntityEquals(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 string ToString()
        {
            return $"[{GetType().Name} {Id}]";
        }
    }
}

提供了主键Id,主键类型可以自定义。

关于EqualityComparer,netstandard类中,也就是.net core中。

#region 程序集 netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
// C:\Users\MaiBenBen\.nuget\packages\netstandard.library\2.0.3\build\netstandard2.0\ref\netstandard.dll
#endregion


namespace System.Collections.Generic
{
    //
    // 摘要:
    //     Provides a base class for implementations of the System.Collections.Generic.IEqualityComparer`1
    //     generic interface.
    //
    // 类型参数:
    //   T:
    //     The type of objects to compare.
    public abstract class EqualityComparer : IEqualityComparer, IEqualityComparer
    {
        //
        // 摘要:
        //     Initializes a new instance of the System.Collections.Generic.EqualityComparer`1
        //     class.
        protected EqualityComparer();

        //
        // 摘要:
        //     Returns a default equality comparer for the type specified by the generic argument.
        //
        // 返回结果:
        //     The default instance of the System.Collections.Generic.EqualityComparer`1 class
        //     for type T.
        public static EqualityComparer Default { get; }

        //
        // 摘要:
        //     When overridden in a derived class, determines whether two objects of type T
        //     are equal.
        //  在派生类中重写时,确定两个类型为T的对象

       //规格相同

        // 参数:
        //   x:
        //     The first object to compare.
        //
        //   y:
        //     The second object to compare.
        //
        // 返回结果:
        //     true if the specified objects are equal; otherwise, false.
        public abstract bool Equals(T x, T y);
        //
        // 摘要:
        //     When overridden in a derived class, serves as a hash function for the specified
        //     object for hashing algorithms and data structures, such as a hash table.
        //
        // 参数:
        //   obj:
        //     The object for which to get a hash code.
        //
        // 返回结果:
        //     A hash code for the specified object.
        //
        // 异常:
        //   T:System.ArgumentNullException:
        //     The type of obj is a reference type and obj is null.
        public abstract int GetHashCode(T obj);
    }
}
ABP