/// <summary> /// Workaround for EF BUG: https://entityframework.codeplex.com/workitem/2074 /// </summary> static void WorkaroundForEntityFrameworkLazyLoadingBug(MemberExpression field, FieldAccessor accessor) { var maybeLazyLoaded = (field.Member is PropertyInfo) && ((PropertyInfo)field.Member).GetAccessors().Any(method => method.Attributes.HasFlag(MethodAttributes.Virtual)); if (maybeLazyLoaded) { var get = accessor.Get; var set = accessor.Set; accessor.Set = (t, v) => { get(t); set(t, v); }; } }
static FieldAccessor Compile(Type type, string fieldName) { var target = Expression.Parameter(typeof(object)); var value = Expression.Parameter(typeof(object)); var field = Expression.PropertyOrField(Expression.Convert(target, type), fieldName); var get = CanReadMember(field.Member) ? Expression.Lambda<Func<object, object>>(Expression.Convert(field, typeof(object)), target).Compile() : t => { throw new NotSupportedException(); }; var set = CanWriteMember(field.Member) ? Expression.Lambda<Action<object, object>>(Expression.Assign(field, Expression.Convert(value, field.Type)), target, value).Compile() : (t, v) => { throw new NotSupportedException(); }; var accessor = new FieldAccessor { Type = field.Type, Get = get, Set = set, }; WorkaroundForEntityFrameworkLazyLoadingBug(field, accessor); return accessor; }