Exemple #1
0
        /// <summary>
        /// Returns the value of the property with the specified name.
        /// </summary>
        /// <param name="target">The object whose property value will be returned.</param>
        /// <param name="name">The name of the property to read.</param>
        /// <returns>The value of the property.</returns>
        public static object GetProperty(object target, string name)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }
            Type            type       = target.GetType();
            Type            memberType = type;
            object          instance   = target;
            IMemberAccessor accessor2  = null;

            foreach (string str in name.Split(new char[] { '.' }))
            {
                if (accessor2 != null)
                {
                    instance   = accessor2.GetValue(instance);
                    memberType = accessor2.MemberType;
                }
                accessor2 = GetAccessor(memberType).FindProperty(str);
            }
            if (accessor2 == null)
            {
                throw new InvalidOperationException(string.Format("Could not find property '{0}' in type '{1}'.", name, type.Name));
            }
            return(accessor2.GetValue(instance));
        }
Exemple #2
0
        public void Link(IRepositoryManager repositoryManager, TSource @object)
        {
            var destRepo         = repositoryManager.GetCommonRepository <TDestination>();
            var idValue          = _fkIdAccessor.GetValue(@object);
            var navPropertyValue = _navPropertyAccessor.GetValue(@object);
            var idHasValue       = idValue != null && idValue != 0;

            if (!idHasValue && navPropertyValue != null)
            {
                _fkIdAccessor.SetValue(@object, navPropertyValue.Id);
            }
            else if (idHasValue)
            {
                navPropertyValue = destRepo.FindById(idValue.Value);
                _navPropertyAccessor.SetValue(@object, navPropertyValue);
            }
            if (navPropertyValue != null && _reverseAccessor != null)
            {
                var collection = GetReverseCollection(navPropertyValue);
                if (CanAddToCollectionPredicate(collection)(@object))
                {
                    collection.Add(@object);
                }
            }
        }
 private static void ShouldBehaveSimilar(IMemberAccessor<TestA, string> ma, TestA a1)
 {
     Assert.That(ma.GetValue(a1), Is.EqualTo(a1.PropString));
     ma.SetValue(a1, "updated " + a1.PropString);
     Assert.That(ma.GetValue(a1), Is.EqualTo(a1.PropString));
     a1.PropString = "new " + a1.PropString;
     Assert.That(ma.GetValue(a1), Is.EqualTo(a1.PropString));
 }
Exemple #4
0
 private static void ShouldBehaveSimilar(IMemberAccessor <TestA, string> ma, TestA a1)
 {
     Assert.That(ma.GetValue(a1), Is.EqualTo(a1.PropString));
     ma.SetValue(a1, "updated " + a1.PropString);
     Assert.That(ma.GetValue(a1), Is.EqualTo(a1.PropString));
     a1.PropString = "new " + a1.PropString;
     Assert.That(ma.GetValue(a1), Is.EqualTo(a1.PropString));
 }
Exemple #5
0
        private void CloneGenericCollection(IMemberAccessor accessor, object originalValue, object target)
        {
            // support readonly collections
            object targetValue = accessor.HasSetter
              ? CreateTargetValue(accessor, originalValue, target)
              : accessor.GetValue(target);

            if (targetValue == null)
            {
                return;
            }

            var sourceList = originalValue as IEnumerable;

            if (sourceList == null)
            {
                return;
            }

            // dynamic wrapper to call generic Add method
            dynamic targetList = new DynamicProxy(targetValue);

            foreach (var sourceItem in sourceList)
            {
                var cloneItem = CloneInstance(sourceItem);
                targetList.Add(cloneItem);
            }

            if (!accessor.HasSetter)
            {
                return;
            }

            accessor.SetValue(target, targetValue);
        }
Exemple #6
0
        private void CloneCollection(IMemberAccessor accessor, object originalValue, object target)
        {
            // support readonly collections
              object targetValue = accessor.HasSetter
            ? CreateTargetValue(accessor, originalValue, target)
            : accessor.GetValue(target);

              if (targetValue == null)
            return;

              var sourceList = originalValue as IEnumerable;
              if (sourceList == null)
            return;

              // must support IList
              var targetList = targetValue as IList;
              if (targetList == null)
            return;

              foreach (var sourceItem in sourceList)
              {
            var cloneItem = CloneInstance(sourceItem);
            targetList.Add(cloneItem);
              }

              if (!accessor.HasSetter)
            return;

              accessor.SetValue(target, targetValue);
        }
Exemple #7
0
        public void ShouldWorkForUnknownTypeAndUnknownMember()
        {
            var             a1 = CreateTestObject();
            IMemberAccessor ma = TypeAccessor.GetMemberAccessor(typeof(TestA), "PropInt");

            Assert.That(ma.GetValue(a1), Is.EqualTo(a1.PropInt));
            ma.SetValue(a1, a1.PropInt + 10);
            Assert.That(ma.GetValue(a1), Is.EqualTo(a1.PropInt));

            IObjectMemberAccessor oma = a1.GetObjectMemberAccessor("Field1");

            Assert.That(oma.GetValue(), Is.EqualTo(a1.Field1));
            oma.SetValue(12.56);
            Assert.That(oma.GetValue(), Is.EqualTo(a1.Field1));
            a1.Field1 -= 345;
            Assert.That(oma.GetValue(), Is.EqualTo(a1.Field1));
        }
Exemple #8
0
        private static object GetMemberValueFromObject(ORMappingItem item, MemberInfo mi, object graph)
        {
            try
            {
                object data = null;

                IMemberAccessor accessor = graph as IMemberAccessor;

                if (accessor != null)
                {
                    data = accessor.GetValue(graph, mi.Name);
                }
                else
                {
                    switch (mi.MemberType)
                    {
                    case MemberTypes.Property:
                        PropertyInfo pi = (PropertyInfo)mi;
                        if (pi.CanRead)
                        {
                            data = pi.GetValue(graph, null);
                        }
                        break;

                    case MemberTypes.Field:
                        FieldInfo fi = (FieldInfo)mi;
                        data = fi.GetValue(graph);
                        break;

                    default:
                        ThrowInvalidMemberInfoTypeException(mi);
                        break;
                    }
                }

                if (data is DateTime)
                {
                    if (item.UtcTimeToLocal)
                    {
                        DateTime dt = (DateTime)data;

                        dt = DateTime.SpecifyKind(dt, DateTimeKind.Unspecified);

                        data = TimeZoneContext.Current.ConvertTimeToUtc(dt);
                    }
                }

                return(data);
            }
            catch (System.Exception ex)
            {
                System.Exception realEx = ExceptionHelper.GetRealException(ex);

                throw new ApplicationException(string.Format("读取属性{0}值的时候出错,{1}", mi.Name, realEx.Message));
            }
        }
Exemple #9
0
        private static void SetValueWithCoercion(IMemberAccessor sourceAccessor, object source, IMemberAccessor targetAccessor, object target)
        {
            Type sType = sourceAccessor.MemberType;
            Type tType = targetAccessor.MemberType;

            object value = sourceAccessor.GetValue(source);
            object v     = ReflectionHelper.CoerceValue(tType, sType, value);

            targetAccessor.SetValue(target, v);
        }
Exemple #10
0
        private ICollection <TSource> GetReverseCollection(TDestination @object)
        {
            var collectionValue = _reverseAccessor.GetValue(@object);

            if (collectionValue == null || collectionValue.IsReadOnly)
            {
                collectionValue = collectionValue == null ? new List <TSource>() : new List <TSource>(collectionValue);
                _reverseAccessor.SetValue(@object, collectionValue);
            }
            return(collectionValue);
        }
Exemple #11
0
        /// <summary>
        /// Returns the value of the property with the specified name.
        /// </summary>
        /// <param name="target">The object whose property value will be returned.</param>
        /// <param name="name">The name of the property to read.</param>
        /// <returns>The value of the property.</returns>
        public static object GetProperty(object target, string name)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            Type   rootType      = target.GetType();
            Type   currentType   = rootType;
            object currentTarget = target;

            TypeAccessor    typeAccessor;
            IMemberAccessor memberAccessor = null;

            // support nested property
            var parts = name.Split('.');

            foreach (var part in parts)
            {
                if (memberAccessor != null)
                {
                    currentTarget = memberAccessor.GetValue(currentTarget);
                    currentType   = memberAccessor.MemberType;
                }

                typeAccessor   = GetAccessor(currentType);
                memberAccessor = typeAccessor.FindProperty(part);
            }

            if (memberAccessor == null)
            {
                throw new InvalidOperationException(String.Format(
                                                        "Could not find property '{0}' in type '{1}'.", name, rootType.Name));
            }

            return(memberAccessor.GetValue(currentTarget));
        }
Exemple #12
0
        private void CloneGenericDictionary(IMemberAccessor accessor, object originalValue, object target)
        {
            // support readonly dictionary
            object targetValue = accessor.HasSetter
              ? CreateTargetValue(accessor, originalValue, target)
              : accessor.GetValue(target);

            if (targetValue == null)
            {
                return;
            }

            // must support IEnumerable
            var sourceList = originalValue as IEnumerable;

            if (sourceList == null)
            {
                return;
            }

            // dynamic wrapper to call generic Add method
            dynamic targetDictionary = new DynamicProxy(targetValue);

            var e = sourceList.GetEnumerator();

            while (e.MoveNext())
            {
                // dynamic wrapper to get the key and value
                dynamic proxy      = new DynamicProxy(e.Current);
                var     keyProxy   = proxy.Key as IDynamicProxy;
                var     valueProxy = proxy.Value as IDynamicProxy;

                if (keyProxy == null)
                {
                    continue;
                }

                object key   = keyProxy.Wrapped;
                object value = valueProxy != null ? valueProxy.Wrapped : null;

                object cloneItem = CloneInstance(value);
                targetDictionary.Add(key, cloneItem);
            }

            if (!accessor.HasSetter)
            {
                return;
            }

            accessor.SetValue(target, targetValue);
        }
Exemple #13
0
        /// <summary>
        /// Attempts to get the value of the Property called <paramref name="name" /> from the underlying Entity.
        /// <remarks>
        /// Only properties that exist on <see cref="EntityType" /> can be retrieved.
        /// Both modified and unmodified properties can be retrieved.
        /// </remarks>
        /// </summary>
        /// <param name="name">The name of the Property</param>
        /// <param name="value">The value of the Property</param>
        /// <param name="target">The target entity to get the value from</param>
        /// <returns>True if the Property was found</returns>
        public bool TryGetPropertyValue(string name, out object value, TEntityType target = null)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            if (_propertiesThatExist.ContainsKey(name))
            {
                IMemberAccessor cacheHit = _propertiesThatExist[name];
                value = cacheHit.GetValue(target ?? _entity);
                return(true);
            }

            value = null;
            return(false);
        }
Exemple #14
0
        private static object GetMemberValueFromObject(MemberInfo mi, object graph)
        {
            try
            {
                object data = null;

                IMemberAccessor accessor = graph as IMemberAccessor;

                if (accessor != null)
                {
                    data = accessor.GetValue(graph, mi.Name);
                }
                else
                {
                    switch (mi.MemberType)
                    {
                    case MemberTypes.Property:
                        PropertyInfo pi = (PropertyInfo)mi;
                        if (pi.CanRead)
                        {
                            data = pi.GetValue(graph, null);
                        }
                        break;

                    case MemberTypes.Field:
                        FieldInfo fi = (FieldInfo)mi;
                        data = fi.GetValue(graph);
                        break;

                    default:
                        ThrowInvalidMemberInfoTypeException(mi);
                        break;
                    }
                }

                return(data);
            }
            catch (System.Exception ex)
            {
                System.Exception realEx = ExceptionHelper.GetRealException(ex);

                throw new ApplicationException(string.Format("读取属性{0}值的时候出错,{1}", mi.Name, realEx.Message));
            }
        }
Exemple #15
0
        /// <summary>
        /// Returns the value of the field with the specified name.
        /// </summary>
        /// <param name="target">The object whose field value will be returned.</param>
        /// <param name="name">The name of the field to read.</param>
        /// <returns>The value of the field.</returns>
        public static object GetField(object target, string name)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }
            Type            type     = target.GetType();
            IMemberAccessor accessor = FindField(type, name);

            if (accessor == null)
            {
                throw new InvalidOperationException(string.Format("Could not find field '{0}' in type '{1}'.", name, type.Name));
            }
            return(accessor.GetValue(target));
        }
Exemple #16
0
        private void CloneDictionary(IMemberAccessor accessor, object originalValue, object target)
        {
            // support readonly dictionary
            var targetValue = accessor.HasSetter
                ? CreateTargetValue(accessor, originalValue, target)
                : accessor.GetValue(target);

            if (targetValue == null)
            {
                return;
            }

            // must support IDictionary
            var sourceList = originalValue as IDictionary;

            if (sourceList == null)
            {
                return;
            }

            var targetList = targetValue as IDictionary;

            if (targetList == null)
            {
                return;
            }

            var e = sourceList.GetEnumerator();

            while (e.MoveNext())
            {
                var cloneItem = CloneInstance(e.Value);
                targetList.Add(e.Key, cloneItem);
            }

            if (!accessor.HasSetter)
            {
                return;
            }

            accessor.SetValue(target, targetValue);
        }
Exemple #17
0
        private void CloneCollection(IMemberAccessor accessor, object originalValue, object target)
        {
            // support readonly collections
            var targetValue = accessor.HasSetter
                ? CreateTargetValue(accessor, originalValue, target)
                : accessor.GetValue(target);

            if (targetValue == null)
            {
                return;
            }

            var sourceList = originalValue as IEnumerable;

            if (sourceList == null)
            {
                return;
            }

            // must support IList
            var targetList = targetValue as IList;

            if (targetList == null)
            {
                return;
            }

            foreach (var sourceItem in sourceList)
            {
                var cloneItem = CloneInstance(sourceItem);
                targetList.Add(cloneItem);
            }

            if (!accessor.HasSetter)
            {
                return;
            }

            accessor.SetValue(target, targetValue);
        }
Exemple #18
0
        /// <summary>
        /// Sets the property value with the specified name.
        /// </summary>
        /// <param name="target">The object whose property value will be set.</param>
        /// <param name="name">The name of the property to set.</param>
        /// <param name="value">The new value to be set.</param>
        /// <remarks>This method supports nested property names. An exmample name would be 'Person.Address.ZipCode'.</remarks>
        /// <param name="flags">A bitmask comprised of one or more <see cref="BindingFlags"/> that specify how the search is conducted.</param>
        public static void SetProperty(object target, string name, object value, BindingFlags flags)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            Type   rootType      = target.GetType();
            Type   currentType   = rootType;
            object currentTarget = target;

            IMemberAccessor memberAccessor = null;

            // support nested property
            var parts = name.Split('.');

            foreach (var part in parts)
            {
                if (memberAccessor != null)
                {
                    currentTarget = memberAccessor.GetValue(currentTarget);
                    currentType   = memberAccessor.MemberType;
                }

                var typeAccessor = TypeAccessor.GetAccessor(currentType);
                memberAccessor = typeAccessor.FindProperty(part, flags);
            }

            if (memberAccessor == null)
            {
                throw new InvalidOperationException($"Could not find property '{name}' in type '{rootType.Name}'.");
            }

            memberAccessor.SetValue(currentTarget, value);
        }
Exemple #19
0
        private static IEnumerable <TestData> Create(MethodInfo testMethod, object testObject, IMemberAccessor accessor)
        {
            Type   returnType = accessor.ReturnType;
            object myValue    = accessor.GetValue(testObject);
            IEnumerable <TestData> results;

            foreach (var c in CONVERSIONS)
            {
                if (c(returnType, myValue, out results))
                {
                    return(results);
                }
            }

            // Otherwise, we can detect the test method signature to determine which
            // interface type is required
            var types = testMethod.GetParameters().Select(p => p.ParameterType).ToArray();

            if (types.Length == 0)
            {
                throw new NotImplementedException();
            }

            if (types.Length == 1)
            {
                // Could be IEnumerable<T> or just T
                if (typeof(IEnumerable <>).MakeGenericType(types[0]).IsAssignableFrom(returnType))
                {
                    return(((IEnumerable)myValue).Cast <object>().Select(t => new TestData(t)));
                }

                if (types[0] == returnType)
                {
                    return(new [] { new TestData(myValue) });
                }
            }
            throw new NotImplementedException();
        }
Exemple #20
0
        private void StartSerialize(object instance, IMemberAccessor memberAccessor)
        {
            var properties = instance.GetType().GetProperties();

            foreach (System.Reflection.PropertyInfo property in properties)
            {
                var type  = property.PropertyType;
                var value = memberAccessor.GetValue(instance, property.Name); //property.GetValue(instance, null);

                if (value == null)
                {
                    this.WriteInt32(-1);
                    continue;
                }

                if (type.Equals(typeof(Boolean)))
                {
                    this.WriteByte((Boolean)value ? (Byte)1 : (Byte)0);
                }
                else if (type.Equals(typeof(Boolean[])))
                {
                    this.WriteArrayBool((Boolean[])value);
                }
                else if (type.Equals(typeof(Byte)))
                {
                    this.WriteByte((Byte)value);
                }
                else if (type.Equals(typeof(Byte[])))
                {
                    this.WriteArrayByte((Byte[])value);
                }
                else if (type.Equals(typeof(Int16)))
                {
                    this.WriteInt16((Int16)value);
                }
                else if (type.Equals(typeof(Int16[])))
                {
                    this.WriteArray((Int16[])value, WriteInt16);
                }
                else if (type.Equals(typeof(Int32)))
                {
                    this.WriteInt32((Int32)value);
                }
                else if (type.Equals(typeof(Int32[])))
                {
                    this.WriteArray((Int32[])value, WriteInt32);
                }
                else if (type.Equals(typeof(Int64)))
                {
                    this.WriteInt64((Int64)value);
                }
                else if (type.Equals(typeof(Int64[])))
                {
                    this.WriteArray((Int64[])value, WriteInt64);
                }
                else if (type.Equals(typeof(String)))
                {
                    this.WriteString((String)value);
                }
                else if (type.Equals(typeof(String[])))
                {
                    this.WriteArray((String[])value, WriteString);
                }
                else if (type.Equals(typeof(Single)))
                {
                    this.WriteFloat((Single)value);
                }
                else if (type.Equals(typeof(Single[])))
                {
                    this.WriteArray((Single[])value, WriteFloat);
                }
                else if (type.Equals(typeof(Double)))
                {
                    this.WriteDouble((Double)value);
                }
                else if (type.Equals(typeof(Double[])))
                {
                    this.WriteArray((Double[])value, WriteDouble);
                }
                else if (type.Equals(typeof(DateTime)))
                {
                    this.WriteDateTime((DateTime)value);
                }
                else if (type.BaseType.Equals(typeof(Enum)))
                {
                    this.WriteEnum(value);
                }
                else if (type.IsArray) //暂时仅支持数组
                {
                    if (type.GetElementType().IsValueType)
                    {
                        throw new Exception("not supported this value array!");
                    }

                    var elementType         = type.GetElementType();
                    var arrayMemberAccessor = memberAccessor.Type.Equals(elementType) ? memberAccessor : DynamicMethodMemberAccessor.FindClassAccessor(elementType);
                    this.WriteArray((Array)value, arrayMemberAccessor);
                }
                else if (type.IsClass)
                {
                    var childerInstanceMemberAccessor = memberAccessor.Type.Equals(property.PropertyType) ? memberAccessor : DynamicMethodMemberAccessor.FindClassAccessor(property.PropertyType);
                    this.WriteInt32(1);//是否为空标志位
                    this.StartSerialize(value, childerInstanceMemberAccessor);
                }
                else
                {
                    throw new Exception("not supported this type:" + type.FullName);
                }
            }
        }
    private void CloneDictionary(IMemberAccessor accessor, object originalValue, object target)
    {
      // support readonly dictionary
      object targetValue = accessor.HasSetter
        ? CreateTargetValue(accessor, originalValue, target)
        : accessor.GetValue(target);

      if (targetValue == null)
        return;

      // must support IDictionary
      var sourceList = originalValue as IDictionary;
      if (sourceList == null)
        return;

      var targetList = targetValue as IDictionary;
      if (targetList == null)
        return;

      var e = sourceList.GetEnumerator();
      while (e.MoveNext())
      {
        var cloneItem = CloneInstance(e.Value);
        targetList.Add(e.Key, cloneItem);
      }

      if (!accessor.HasSetter)
        return;

      accessor.SetValue(target, targetValue);
    }
        private void CloneGenericDictionary(IMemberAccessor accessor, object originalValue, object target)
        {
            // support readonly dictionary
            object targetValue = accessor.HasSetter
              ? CreateTargetValue(accessor, originalValue, target)
              : accessor.GetValue(target);

            if (targetValue == null)
                return;

            // must support IEnumerable
            var sourceList = originalValue as IEnumerable;
            if (sourceList == null)
                return;

            // dynamic wrapper to call generic Add method
            dynamic targetDictionary = new DynamicProxy(targetValue);
            
            var e = sourceList.GetEnumerator();
            while (e.MoveNext())
            {
                // dynamic wrapper to get the key and value
                dynamic proxy = new DynamicProxy(e.Current);
                var keyProxy = proxy.Key as IDynamicProxy;
                var valueProxy = proxy.Value as IDynamicProxy;

                if (keyProxy == null)
                    continue;

                object key = keyProxy.Wrapped;
                object value = valueProxy != null ? valueProxy.Wrapped : null;

                object cloneItem = CloneInstance(value);
                targetDictionary.Add(key, cloneItem);
            }

            if (!accessor.HasSetter)
                return;

            accessor.SetValue(target, targetValue);
        }
        private void CloneGenericCollection(IMemberAccessor accessor, object originalValue, object target)
        {
            // support readonly collections
            object targetValue = accessor.HasSetter
              ? CreateTargetValue(accessor, originalValue, target)
              : accessor.GetValue(target);

            if (targetValue == null)
                return;

            var sourceList = originalValue as IEnumerable;
            if (sourceList == null)
                return;

            // dynamic wrapper to call generic Add method
            dynamic targetList = new DynamicProxy(targetValue);
            
            foreach (var sourceItem in sourceList)
            {
                var cloneItem = CloneInstance(sourceItem);
                targetList.Add(cloneItem);
            }

            if (!accessor.HasSetter)
                return;

            accessor.SetValue(target, targetValue);
        }
 public void should_be_able_to_read_a_value_of_the_property()
 {
     _result.GetValue(_project);
 }
Exemple #25
0
 public TMember GetValue()
 {
     return(_rtAccessor.GetValue(_object));
 }
 public object ResolveValue(object source)
 {
     return(_memberAccessor.GetValue(source));
 }
Exemple #27
0
        private void WriteRelationships(AuditEntryState state)
        {
            var properties = state.EntityType.NavigationProperties;

            if (properties.Count == 0)
            {
                return;
            }

            var modifiedMembers = state.ObjectStateEntry
                                  .GetModifiedProperties()
                                  .ToList();

            var type = state.ObjectType;

            var currentValues = state.IsDeleted
                ? state.ObjectStateEntry.OriginalValues
                : state.ObjectStateEntry.CurrentValues;

            var originalValues = state.IsModified
                ? state.ObjectStateEntry.OriginalValues
                : null;

            foreach (NavigationProperty navigationProperty in properties)
            {
                if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ||
                    navigationProperty.FromEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many)
                {
                    continue;
                }

                string name = navigationProperty.Name;
                if (configuration.IsNotAudited(type, name))
                {
                    continue;
                }

                var             accessor      = state.EntityAccessor.Find(name);
                IMemberAccessor displayMember = configuration.GetDisplayMember(accessor.MemberType);
                if (displayMember == null)
                {
                    continue; // no display property, skip
                }
                bool isModified = IsModifed(navigationProperty, modifiedMembers);

                if (state.IsModified && !isModified)
                {
                    continue; // this means the property was not changed, skip it
                }
                bool isLoaded = IsLoaded(state, navigationProperty, accessor);
                if (!isLoaded)
                {
                    continue;
                }

                var auditProperty = new AuditProperty();

                try
                {
                    auditProperty.Name           = name;
                    auditProperty.Type           = accessor.MemberType.FullName;
                    auditProperty.IsRelationship = true;
                    //auditProperty.ForeignKey = GetForeignKey(navigationProperty);

                    object currentValue = null;

                    if (isLoaded)
                    {
                        // get value directly from instance to save db call
                        object valueInstance = accessor.GetValue(state.Entity);
                        if (valueInstance != null)
                        {
                            currentValue = displayMember.GetValue(valueInstance);
                        }
                    }
                    else
                    {
                        // get value from db
                        currentValue = GetDisplayValue(state, navigationProperty, displayMember, currentValues);
                    }

                    // format
                    //currentValue = FormatValue(state, name, currentValue);

                    if (!state.IsModified && currentValue == null)
                    {
                        continue; // skip null value
                    }
                    switch (state.AuditEntity.Action)
                    {
                    case ObjectStateType.Added:
                        auditProperty.Current = currentValue;
                        break;

                    case ObjectStateType.Modified:
                        auditProperty.Current = currentValue ?? _nullText;
                        object originalValue = GetDisplayValue(state, navigationProperty, displayMember, originalValues);
                        //originalValue = FormatValue(state, name, originalValue);
                        auditProperty.Original = originalValue;
                        break;

                    case ObjectStateType.Deleted:
                        auditProperty.Original = currentValue;
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError(ex.Message);
                    if (state.IsDeleted)
                    {
                        auditProperty.Original = _errorText;
                    }
                    else
                    {
                        auditProperty.Current = _errorText;
                    }
                }

                state.AuditEntity.Properties.Add(auditProperty);
            }
        }
 public object GetValue(object instance)
 {
     return(_derived.GetValue(
                _initial.GetValue(instance)
                ));
 }