Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #7
0
        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);
        }