private static Reflection.PropertyInfo FindPrimaryKey(Type contractType, Type entityType) { var properties = GetProperties(contractType); //Проверяем, вдруг у контракта для первичного ключа задан атрибут Reflection.PropertyInfo keyProperty = properties.SingleOrDefault(pr => pr.CustomAttributes.Any(a => a.AttributeType == typeof(KeyAttribute))); if (keyProperty == null) { //В контракте атрибут не задан. if (entityType != null) { //Поищем этот атрибут у свойств сущности var entityProperties = GetProperties(entityType); Reflection.PropertyInfo entityKeyProperty = entityProperties.SingleOrDefault(pr => pr.CustomAttributes.Any(a => a.AttributeType == typeof(KeyAttribute))); if (entityKeyProperty == null) { entityKeyProperty = entityProperties.SingleOrDefault(pi => pi.Name.Equals("id", StringComparison.InvariantCultureIgnoreCase)); } if (entityKeyProperty != null) { keyProperty = FindProperty(properties, entityKeyProperty.Name); } } else { keyProperty = properties.SingleOrDefault(pi => pi.Name.Equals("id", StringComparison.InvariantCultureIgnoreCase)); } } return(keyProperty); }
public static Expression GetPropertyAccessLambda(Type type, Reflection.PropertyInfo propertyInfo) { ParameterExpression p1 = Expression.Parameter(type, "p1"); MemberExpression propertyOnP1 = Expression.Property(p1, propertyInfo.GetGetMethod()); return(Expression.Lambda(propertyOnP1, p1)); }
public DependentNavigationPropertyConfiguration <TEntityType> WithMany( Reflection.PropertyInfo propertyInfo) { Check.NotNull(propertyInfo, "propertyInfo"); _navigationPropertyConfiguration.InverseNavigationProperty = propertyInfo; return(WithMany()); }
public CascadableNavigationPropertyConfiguration HasForeignKey( Reflection.PropertyInfo propertyInfo) { Check.NotNull(propertyInfo, "propertyInfo"); NavigationPropertyConfiguration.Constraint = new ForeignKeyConstraintConfiguration(new Reflection.PropertyInfo[] { propertyInfo }); return(this); }
static IOrderedQueryable <T> ApplyOrder <T>( IQueryable <T> source, string property, string methodName) { ; string[] props = property.Split(new char[] { ',', ';' }); Type type = typeof(T); Expressions.ParameterExpression arg = Expressions.Expression.Parameter(type, "x"); Expressions.Expression expr = arg; foreach (string prop in props) { // use reflection (not ComponentModel) to mirror LINQ Reflection.PropertyInfo pi = type.GetProperty(prop); if (pi == null) { Reflection.FieldInfo fi = type.GetField(prop); expr = Expressions.Expression.Field(expr, fi); type = fi.FieldType; } else { expr = Expressions.Expression.Property(expr, pi); type = pi.PropertyType; } } // Next prop Type delegateType = typeof(Func <,>).MakeGenericType(typeof(T), type); Expressions.LambdaExpression lambda = Expressions.Expression.Lambda(delegateType, expr, arg); object result = typeof(Queryable).GetMethods().Single( method => method.Name == methodName && method.IsGenericMethodDefinition && method.GetGenericArguments().Length == 2 && method.GetParameters().Length == 2) .MakeGenericMethod(typeof(T), type) .Invoke(null, new object[] { source, lambda }); return((IOrderedQueryable <T>)result); } // End Function ApplyOrder
private static bool isForeignKey(Reflection.PropertyInfo targetField, object target, out Reflection.PropertyInfo navigationProperty) { navigationProperty = null; if (targetField.PropertyType.IsClass || targetField.PropertyType.IsInterface) { return(false); } var properties = GetProperties(target.GetType()); //Если для свойства внешнего ключа указан атрибут ForeignKey, то его имя указывает на свойство навигации string navigationPropertyName = targetField.GetCustomAttributes(true).OfType <ForeignKeyAttribute>().SingleOrDefault()?.Name; if (!string.IsNullOrWhiteSpace(navigationPropertyName)) { navigationProperty = properties.SingleOrDefault(p => p.Name == navigationPropertyName); return(true); } //Если для свойства навигации указан атрибут ForeignKey, то его имя указывает на свойство внешнего ключа, которое должно быть равно текущему свойству navigationProperty = properties.SingleOrDefault(pr => pr.CustomAttributes.Any(ca => ca.AttributeType == typeof(ForeignKeyAttribute)) && pr.GetCustomAttributes(true).OfType <ForeignKeyAttribute>().Any(at => at.Name == targetField.Name)); if (navigationProperty != null) { return(true); } //Атрибут ForeignKey не указан - попробуем найти свойство по соглашению имен. if (targetField.Name.EndsWith("id", StringComparison.InvariantCultureIgnoreCase)) { string expectedName = targetField.Name.Substring(0, targetField.Name.Length - 2); if (expectedName.EndsWith("_")) { expectedName = expectedName.Substring(0, expectedName.Length - 1); } navigationProperty = FindProperty(properties, expectedName); } return(navigationProperty != null); }
private TSource Find(TTarget target) { Reflection.PropertyInfo targetKey = FindPrimaryKey(typeof(TTarget), null); Reflection.PropertyInfo sourceKey = FindPrimaryKey(typeof(TSource), typeof(TTarget)); if (sourceKey != null && targetKey == null) { //Если нашли ключ в источнике, но не нашли в целевом типе - бывает и такое, когда KeyAttribute указан у источника, а не у целевого. //Просто поищем ключ в целевом объекте еще раз targetKey = FindProperty(GetProperties(typeof(TTarget)), sourceKey.Name); } if (sourceKey == null) { throw new CopyToException($"Не удалось найти первичный ключ в классе {typeof(TSource).FullName} и выражение сопоставления также не было указано методом Match"); } if (sourceKey == null) { throw new CopyToException($"Не удалось найти первичный ключ в классе {typeof(TTarget).FullName} и выражение сопоставления также не было указано методом Match"); } object targetKeyValue = ConvertToTarget(targetKey.GetValue(target), sourceKey.PropertyType, new Dictionary <object, object>()); return(Source.SingleOrDefault(s => sourceKey.GetValue(s).Equals(targetKeyValue))); }
public static void UpdateFrom(object target, object source) { var targetFields = GetProperties(target.GetType()); var sourceFields = GetProperties(source.GetType()); foreach (var targetProperty in targetFields) { try { //Если поле является свойством внешнего ключа if (isForeignKey(targetProperty, target, out var navigationProperty) && navigationProperty != null) { var sourceNavigationProperty = FindProperty(sourceFields, navigationProperty.Name); object sourceNavigationValue; if (sourceNavigationProperty != null && (sourceNavigationValue = sourceNavigationProperty.GetValue(source)) != null) { //В контракте нашли объект, соответсвующий свойству навигации сущности object keyValue = FindPrimaryKeyValue(sourceNavigationValue, navigationProperty.PropertyType); object value = ConvertToTarget(keyValue, targetProperty.PropertyType, new Dictionary <object, object>()); targetProperty.SetValue(target, value); navigationProperty?.SetValue(target, null); continue; } else { //В контракте не нашли объект, соответствующий свойству навигации сущности - пойдем по основному сценарию ниже } } if ((targetProperty.PropertyType.IsClass || targetProperty.PropertyType.IsInterface) && (targetProperty.PropertyType != typeof(string))) { //дочерние классы и коллекции не изменяем - оставляем это дело вызывающей стороне continue; } Reflection.PropertyInfo sourceProperty = FindProperty(sourceFields, targetProperty.Name); if (sourceProperty == null) { continue; } object sourceValue = sourceProperty?.GetValue(source); object targetOriginalValue = targetProperty.GetValue(target); //Не присваиваем значение, если они и так равны if (sourceValue == targetOriginalValue || sourceValue?.ToString() == targetOriginalValue?.ToString()) { continue; } object targetValue = ConvertToTarget(sourceValue, targetProperty.PropertyType, new Dictionary <object, object>()); targetProperty.SetValue(target, targetValue); } catch (Exception e) { throw new CopyToException($"UpdateFrom fieldName {targetProperty.Name}. Target: <{target}>. Source: <{source}> ", e); } //End foreach } }
public static object FindPrimaryKeyValue(object contract, Type entityType) { Reflection.PropertyInfo keyProperty = FindPrimaryKey(contract.GetType(), entityType); return(keyProperty?.GetValue(contract)); }
public OptionalNavigationPropertyConfiguration <TEntityType, TTargetEntity> HasOptional <TTargetEntity>(Reflection.PropertyInfo propertyInfo) where TTargetEntity : class { Check.NotNull(propertyInfo, "propertyInfo"); return(new OptionalNavigationPropertyConfiguration <TEntityType, TTargetEntity>( _entityTypeConfiguration.Navigation(propertyInfo))); }