/// <summary>Check null recursive.</summary> /// <param name="currentItem">The current item.</param> /// <param name="paths">The paths.</param> /// <param name="index">Zero-based index of the.</param> public static void CheckNullRecursive(object currentItem, List <string> paths, int index) { var currentItemEnumerable = currentItem as IEnumerable; var path = paths[index]; if (currentItemEnumerable != null) { foreach (var item in currentItemEnumerable) { CheckNullRecursive(item, paths, index); } } else { var property = currentItem.GetType().GetProperty(path, BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); if (property != null) { var accessor = new PropertyOrFieldAccessor(property); var value = accessor.GetValue(currentItem); if (value == null) { CheckAndSetCollection(accessor, currentItem, property.PropertyType, property.PropertyType); return; } if (index + 1 < paths.Count) { CheckNullRecursive(value, paths, index + 1); } } } }
private static void CheckAndSetCollection(PropertyOrFieldAccessor accessor, object currentItem, Type propertyType, Type originalType) { if (propertyType.GetGenericArguments().Length == 1 && typeof(IEnumerable).IsAssignableFrom(propertyType)) { object value; var genericTypeDefinition = propertyType.GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(ICollection <>)) { value = Activator.CreateInstance(typeof(HashSet <>).MakeGenericType(propertyType.GetGenericArguments()[0])); } else if (genericTypeDefinition == typeof(IList <>) || genericTypeDefinition == typeof(IEnumerable <>)) { value = Activator.CreateInstance(typeof(List <>).MakeGenericType(propertyType.GetGenericArguments()[0])); } else { // Create an instance of the original type since we know it implement one of the type supported: List<A> value = Activator.CreateInstance(originalType); } accessor.SetValue(currentItem, value); } else { if (propertyType.BaseType != null && propertyType.BaseType != typeof(object)) { CheckAndSetCollection(accessor, currentItem, propertyType.BaseType, originalType); } } }
/// <summary>Check null recursive.</summary> /// <param name="currentItem">The current item.</param> /// <param name="paths">The paths.</param> /// <param name="index">Zero-based index of the.</param> public static void SetLazyLoaded(object currentItem, List <string> paths, int index) { var currentItemEnumerable = currentItem as IEnumerable; var path = paths[index]; if (currentItemEnumerable != null) { foreach (var item in currentItemEnumerable) { SetLazyLoaded(item, paths, index); } } else { if (!currentItem.GetType().FullName.StartsWith("System.Data.Entity.DynamicProxies.", StringComparison.InvariantCulture)) { return; } var entityWrapperField = currentItem.GetType().GetField("_entityWrapper", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var entityWrapper = entityWrapperField.GetValue(currentItem); var relationshipManagerProperty = entityWrapper.GetType().GetProperty("RelationshipManager", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var relationshipManager = (System.Data.Entity.Core.Objects.DataClasses.RelationshipManager)relationshipManagerProperty.GetValue(entityWrapper, null); foreach (var related in relationshipManager.GetAllRelatedEnds()) { var navigationPropertyProperty = related.GetType().GetProperty("NavigationProperty", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var navigationProperty = (System.Data.Entity.Core.Metadata.Edm.NavigationProperty)navigationPropertyProperty.GetValue(related, null); if (navigationProperty != null && navigationProperty.Name == path) { related.IsLoaded = true; var property = currentItem.GetType().GetProperty(path, BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); if (property != null) { var accessor = new PropertyOrFieldAccessor(property); var value = accessor.GetValue(currentItem); if (value == null) { return; } if (index + 1 < paths.Count) { SetLazyLoaded(value, paths, index + 1); } } } } } }
/// <summary>Check null recursive.</summary> /// <param name="currentItem">The current item.</param> /// <param name="paths">The paths.</param> /// <param name="index">Zero-based index of the.</param> public static void CheckNullRecursive(object currentItem, List <string> paths, int index) { var currentItemEnumerable = currentItem as IEnumerable; var path = paths[index]; if (currentItemEnumerable != null) { foreach (var item in currentItemEnumerable) { CheckNullRecursive(item, paths, index); } } else { var property = currentItem.GetType().GetProperty(path, BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); if (property != null) { var accessor = new PropertyOrFieldAccessor(property); var value = accessor.GetValue(currentItem); if (value == null) { if (property.PropertyType.GetGenericArguments().Length == 1) { var genericTypeDefinition = property.PropertyType.GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(ICollection <>)) { value = Activator.CreateInstance(typeof(HashSet <>).MakeGenericType(property.PropertyType.GetGenericArguments()[0])); } else if (genericTypeDefinition == typeof(IList <>)) { value = Activator.CreateInstance(typeof(List <>).MakeGenericType(property.PropertyType.GetGenericArguments()[0])); } else { value = Activator.CreateInstance(property.PropertyType); } accessor.SetValue(currentItem, value); } return; } if (index + 1 < paths.Count) { CheckNullRecursive(value, paths, index + 1); } } } }