using Ant.Common; using Ant.Descriptors; using Ant.ORM; using Ant.Utility; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Ant.Core { /// /// /// public interface IEntityState { /// /// /// object Entity { get; } /// /// /// MetaData TypeDescriptor { get; } /// /// /// /// /// /// bool HasChanged(MappingMemberDescriptor memberDescriptor, object val); /// /// /// void Refresh(); } class EntityState : IEntityState { Dictionary _fakes; object _entity; MetaData _typeDescriptor; public EntityState(MetaData typeDescriptor, object entity) { this._typeDescriptor = typeDescriptor; this._entity = entity; this.Refresh(); } public object Entity { get { return this._entity; } } public MetaData TypeDescriptor { get { return this._typeDescriptor; } } public bool HasChanged(MappingMemberDescriptor memberDescriptor, object val) { object oldVal; if (!this._fakes.TryGetValue(memberDescriptor.MemberInfo, out oldVal)) { return true; } if (memberDescriptor.MemberInfoType == UtilConstants.TypeOfByteArray) { //byte[] is a big big hole~ return !AreEqual((byte[])oldVal, (byte[])val); } return !AntUtils.AreEqual(oldVal, val); } public void Refresh() { Dictionary mappingMemberDescriptors = this.TypeDescriptor.FiledMeta.MappingMemberDescriptors; if (this._fakes == null) { this._fakes = new Dictionary(mappingMemberDescriptors.Count); } else { this._fakes.Clear(); } object entity = this._entity; foreach (var kv in mappingMemberDescriptors) { MemberInfo key = kv.Key; MappingMemberDescriptor memberDescriptor = kv.Value; var val = memberDescriptor.GetValue(entity); //I hate the byte[]. if (memberDescriptor.MemberInfoType == UtilConstants.TypeOfByteArray) { val = Clone((byte[])val); } this._fakes[key] = val; } } static byte[] Clone(byte[] arr) { if (arr == null) return null; byte[] ret = new byte[arr.Length]; for (int i = 0; i < arr.Length; i++) { ret[i] = arr[i]; } return ret; } static bool AreEqual(byte[] obj1, byte[] obj2) { if (obj1 == obj2) return true; if (obj1 != null && obj2 != null) { if (obj1.Length != obj2.Length) return false; for (int i = 0; i < obj1.Length; i++) { if (obj1[i] != obj2[i]) return false; } return true; } return false; } } }