public T Update <T, TResult>(T entity, params Expression <Func <T, TResult> >[] selectedProperties) where T : class, IEntity { foreach (var s in selectedProperties) { var projectionLambda = s as LambdaExpression; MemberExpression member = ParameterHelper.GetMemberExpression(projectionLambda); var propertyInfo = (PropertyInfo)member.Member; var propertyName = propertyInfo.Name; var propertyType = propertyInfo.PropertyType; context.Entry(entity).Property(propertyName).IsModified = true; } return(entity); }
public INavigationPropertySelectorBuilder <T> Include(Expression <Func <T, object> > navigationProperty) { LabelExpression l = navigationProperty as LabelExpression; var propertyInfo = (PropertyInfo)ParameterHelper.GetMemberExpression(navigationProperty as LambdaExpression).Member; var propertyNameOfReferer = propertyInfo.Name; _navigationProperties = navigationProperty; //var navigationProperty = new NavigationProperty( // propertyNameOfReferer, // typeof(TProperty).Name, // typeof(TProperty)); //navigationProperty.Projections.AddRange(selectedProperties); return(this); }
ISelectPropertyBuilder <T> ISelectPropertyBuilder <T> .Include <TProperty>( Expression <Func <T, dynamic> > navigationPropery, params Expression <Func <TProperty, dynamic> >[] selectedProperties) { var propertyInfo = (PropertyInfo)ParameterHelper.GetMemberExpression(navigationPropery as LambdaExpression).Member; var propertyNameOfReferer = propertyInfo.Name; var navigationProperty = new NavigationProperty( propertyNameOfReferer, typeof(TProperty).Name, typeof(TProperty)); navigationProperty.Projections.AddRange(selectedProperties); AllProjections.NavigationPropertiesProjections.Add(navigationProperty); // TODO: Maybe remove any tracked entities of the navigation property type (and id), when return(this); }
IUpdatePropertyBuilder <T> IUpdatePropertyBuilder <T> .IncludeNavigationProperyUpdate <TProperty>( int id, Expression <Func <T, dynamic> > navigationPropery, params Expression <Func <TProperty, dynamic> >[] selectedProperties) { var propertyInfo = (PropertyInfo)ParameterHelper.GetMemberExpression(navigationPropery as LambdaExpression).Member; var propertyNameOfReferer = propertyInfo.Name; var navigationProperty = new NavigationProperty( propertyNameOfReferer, typeof(TProperty).Name, typeof(TProperty)) { Id = id }; navigationProperty.Projections.AddRange(selectedProperties); AllProjections.NavigationPropertiesProjections.Add(navigationProperty); return(this); }
private string CreateCacheKey() { StringBuilder sb = new StringBuilder(); foreach (LambdaExpression le in BaseEntityProjections) { MemberExpression member = ParameterHelper.GetMemberExpression(le); var propertyInfo = (PropertyInfo)member.Member; var declaringType = propertyInfo.DeclaringType; var propertyName = propertyInfo.Name; var propertyType = propertyInfo.PropertyType; sb.Append(":" + declaringType + ":" + propertyName + ":" + propertyType + ":"); } sb.Append(":"); foreach (INavigationProperty np in NavigationPropertiesProjections) { sb.Append(np.Name + ":" + np.Type); foreach (LambdaExpression le in np.Projections) { MemberExpression member = ParameterHelper.GetMemberExpression(le); var propertyInfo = (PropertyInfo)member.Member; var declaringType = propertyInfo.DeclaringType; var propertyName = propertyInfo.Name; var propertyType = propertyInfo.PropertyType; sb.Append(":" + declaringType + ":" + propertyName + ":" + propertyType + ":"); } } return(sb.ToString()); }
private Type CreateLambbda(out Expression <Func <T, dynamic> > lambda) { /* * Based in the follwing: * * var projector = rep.PropertySelectBuilder(blog) * .Select(p => p.Name) * .Include<Post>(m => m.Posts, p => p.Text) * .Build(); * * * Output lambda to be used as expression in: * * context.Set<T>(). * Where(p => p.Id == id). * Select(lamdba.Expression). * Single(); * * * where lambda will look (using AllProjections in the builder), using example projector above * * p = new * { * p => p.Name, * Posts = from post in context.Set<Post>() * where post.BlogId == _id * select new * { * Text = pp.Text * } * } */ List <KeyValuePair <string, Type> > anonymousTypeProperties = new List <KeyValuePair <string, Type> >(); List <Expression> anonymousTypePropertiesValues = new List <Expression>(); ParameterExpression lambdaParameter = Expression.Parameter(typeof(T), "p"); foreach (var projection in AllProjections.BaseEntityProjections) { var projectionLambda = projection as LambdaExpression; MemberExpression member = ParameterHelper.GetMemberExpression(projectionLambda); var propertyInfo = (PropertyInfo)member.Member; var propertyName = propertyInfo.Name; var propertyType = propertyInfo.PropertyType; var memberAccess = Expression.Property(lambdaParameter, propertyName); anonymousTypeProperties.Add(new KeyValuePair <string, Type>(propertyName, propertyType)); anonymousTypePropertiesValues.Add(memberAccess); } foreach (var navigationProperty in AllProjections.NavigationPropertiesProjections) { var navigationProperyType = navigationProperty.Type; // Creates the <T>.where(p => p.id == id) part of the expression MethodCallExpression whereCallExpression = CreateWhereCall <T>(_id, navigationProperyType); ParameterExpression p1 = Expression.Parameter(navigationProperyType, "p1"); var navigationPropertyAnoymousTypeProperties = new List <KeyValuePair <string, Type> >(); List <MemberExpression> navigationPropertyAnoymousTypePropertiesValues = new List <MemberExpression>(); foreach (var projection in navigationProperty.Projections) { var navigationPropertyProjection = projection as LambdaExpression; MemberExpression member = ParameterHelper.GetMemberExpression(navigationPropertyProjection); var propertyInfo = (PropertyInfo)member.Member; var propertyName = propertyInfo.Name; var propertyType = propertyInfo.PropertyType; var memberAccess = Expression.Property(p1, propertyName); navigationPropertyAnoymousTypeProperties.Add(new KeyValuePair <string, Type>(propertyName, propertyType)); navigationPropertyAnoymousTypePropertiesValues.Add(memberAccess); } var anonymousTypeOfNavigationPropertyProjection = AnonymousTypeUtils.CreateType(navigationPropertyAnoymousTypeProperties); Type typeOfSubProj = null; var anonymousTypeOfNavigationPropertyProjectionConstructor = anonymousTypeOfNavigationPropertyProjection .GetConstructor(navigationPropertyAnoymousTypeProperties.Select(kv => kv.Value).ToArray()); typeOfSubProj = anonymousTypeOfNavigationPropertyProjectionConstructor.ReflectedType; var selectMethod = typeof(Queryable).GetMethods().Where(m => m.Name == "Select").ToList()[0]; var genericSelectMethod = selectMethod.MakeGenericMethod(navigationProperyType, typeOfSubProj); var newInstanceOfTheGenericType = Expression.New(anonymousTypeOfNavigationPropertyProjectionConstructor, navigationPropertyAnoymousTypePropertiesValues); var projectionLamdba = Expression.Lambda(newInstanceOfTheGenericType, p1); MethodCallExpression selctCallExpression = Expression.Call( genericSelectMethod, whereCallExpression, projectionLamdba); var provider = ((IQueryable)_context.Set <T>()).Provider; // TODO, Is it ok to assume navigation properties has the same provider? var theMethods = typeof(IQueryProvider).GetMethods(); var createQMethd = theMethods.Where(name => name.Name == "CreateQuery").ToList()[1]; var speciifMethod = createQMethd.MakeGenericMethod(anonymousTypeOfNavigationPropertyProjectionConstructor.ReflectedType); var navigationProppertyQueryWithProjection1 = speciifMethod.Invoke(provider, new object[] { selctCallExpression }); Type genericFunc = typeof(IEnumerable <>); Type funcOfTypeOfSubProj = genericFunc.MakeGenericType(typeOfSubProj); var allMethodsOnEnumerableClass = typeof(Enumerable).GetMethods(); var genericToListMethod = allMethodsOnEnumerableClass.Where(m => m.Name == "ToList").ToList()[0]; var toListOfTypeOfSubProj = genericToListMethod.MakeGenericMethod(typeOfSubProj); MethodCallExpression toListExpression11 = Expression.Call( toListOfTypeOfSubProj, Expression.Constant(navigationProppertyQueryWithProjection1)); anonymousTypeProperties.Add(new KeyValuePair <string, Type>(navigationProperty.Name, funcOfTypeOfSubProj)); anonymousTypePropertiesValues.Add(toListExpression11); } var projectedEntityAnonymousType = AnonymousTypeUtils.CreateType(anonymousTypeProperties); var constructor = projectedEntityAnonymousType.GetConstructor(anonymousTypeProperties.Select(p => p.Value).ToArray()); var anonymousTypeInstance = Expression.New(constructor, anonymousTypePropertiesValues); lambda = Expression.Lambda <Func <T, dynamic> >(anonymousTypeInstance, lambdaParameter); return(projectedEntityAnonymousType); }
public T UpdateGraph <T>(T entity, IPropertyUpdater <T> projection) where T : class, IEntity { var allTrackedEntries = new List <EntityEntry>(context.ChangeTracker.Entries()); var allProperties = context.Entry(entity).Metadata.GetProperties().Select(p => p.Name); var propertiesToBeUpdated = new List <string>(); foreach (var p in projection.AllProjections.BaseEntityProjections) { var projectionLambda = p as LambdaExpression; MemberExpression member = ParameterHelper.GetMemberExpression(projectionLambda); var propertyInfo = (PropertyInfo)member.Member; var propertyName = propertyInfo.Name; var propertyType = propertyInfo.PropertyType; context.Entry(entity).Property(propertyName).IsModified = true; propertiesToBeUpdated.Add(propertyName); } var propertiesToBeResetSinveTheyAreNotRequestedToBeUpdated = allProperties.Except(propertiesToBeUpdated); foreach (var propName in propertiesToBeResetSinveTheyAreNotRequestedToBeUpdated) { context.Entry(entity).Property(propName).CurrentValue = context.Entry(entity).Property(propName).OriginalValue; } foreach (var p in projection.AllProjections.NavigationPropertiesProjections) { var subentity = context.ChangeTracker .Entries() .SingleOrDefault(e => e.Metadata.ClrType.Name == p.Name && p.Id == (int)e.Property("Id").CurrentValue); if (subentity == null) { continue; } var ahag = allTrackedEntries.Find(e => e.Metadata.ClrType.Name == p.Name && p.Id == (int)e.Property("Id").CurrentValue); allTrackedEntries.Remove(ahag); var allPropertieOfNavigationPropertys = subentity.Metadata.GetProperties().Select(p1 => p1.Name); var keyProperties = subentity.Metadata.GetKeys().SelectMany(p2 => p2.Properties).Select(p3 => p3.Name); var navigationPropertiesToBeUpdated = new List <string>(); foreach (var pp in p.Projections) { var projectionLambda = pp as LambdaExpression; MemberExpression member = ParameterHelper.GetMemberExpression(projectionLambda); var propertyInfo = (PropertyInfo)member.Member; var propertyName = propertyInfo.Name; var propertyType = propertyInfo.PropertyType; if (keyProperties.Contains(propertyName)) { continue; } subentity.Property(propertyName).IsModified = true; navigationPropertiesToBeUpdated.Add(propertyName); } var navigationPropertiesToBeResetSinveTheyAreNotRequestedToBeUpdated = allPropertieOfNavigationPropertys.Except(navigationPropertiesToBeUpdated); foreach (var propName in navigationPropertiesToBeResetSinveTheyAreNotRequestedToBeUpdated) { subentity.Property(propName).CurrentValue = subentity.Property(propName).OriginalValue; } } var ahag11 = allTrackedEntries.Find(e => e.Metadata.ClrType.Name == context.Entry(entity).Metadata.ClrType.Name&& entity.Id == (int)e.Property("Id").CurrentValue); allTrackedEntries.Remove(ahag11); foreach (var e in allTrackedEntries) { var allPropertieOfNavigationPropertys = e.Metadata.GetProperties().Select(p1 => p1.Name); foreach (var eey in allPropertieOfNavigationPropertys) { e.Property(eey).CurrentValue = e.Property(eey).OriginalValue; } e.State = EntityState.Unchanged; } return(entity); }