Example #1
0
        private static void MaterializeNavigationPropertiesObsolete <T>(
            dynamic mainEntity,
            dynamic projectedEntity,
            Type projectedEntityAnonymousType,
            ISelectPropertyBuilder <T> selectedSelectProperties) where T : class, IEntity
        {
            Type genericListType      = typeof(List <>);
            var  genericDynamicMapper = typeof(Mapper).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(m => m.Name == "DynamicMap").ToList()[2];

            foreach (var projection in selectedSelectProperties.AllProjections.NavigationPropertiesProjections)
            {
                var navigationPropertyOnMainEntity             = typeof(T).GetProperty(projection.ReferingPropertyName);
                var navigationPropertyOnProjectedAnonymousType = projectedEntityAnonymousType.GetProperty(projection.Name);

                var propertValues = (IEnumerable)navigationPropertyOnProjectedAnonymousType.GetValue(projectedEntity);

                Type listOfTypeProjectionType = genericListType.MakeGenericType(new[] { projection.Type });

                var   mapperOfProjectionType = genericDynamicMapper.MakeGenericMethod(projection.Type);
                IList navigationPropertyList = (IList)Activator.CreateInstance(listOfTypeProjectionType);
                foreach (var value in propertValues)
                {
                    var valueOfNavigationPropertyProjection = mapperOfProjectionType.Invoke(null, new object[] { value });

                    navigationPropertyList.Add(valueOfNavigationPropertyProjection);
                }

                navigationPropertyOnMainEntity.SetValue(mainEntity, navigationPropertyList);
            }
        }
Example #2
0
        public T RetrieveByIdOld <T>(int id, ISelectPropertyBuilder <T> selectedSelectProperties) where T : class, IEntity
        {
            // The query will be projected onto an anonymous type.
            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 selectedSelectProperties.AllProjections.BaseEntityProjections)
            {
                var projectionLambda = projection as LambdaExpression;

                MemberExpression member = CreateMemberExpression(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 selectedSelectProperties.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 = CreateMemberExpression(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 assube 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);
            }

            Type projectedEntityAnonymousType = AnonymousTypeUtils.CreateType(anonymousTypeProperties);

            var constructor = projectedEntityAnonymousType.GetConstructor(anonymousTypeProperties.Select(p => p.Value).ToArray());

            var anonymousTypeInstance = Expression.New(constructor, anonymousTypePropertiesValues);

            Expression <Func <T, dynamic> > lambd11a1 = Expression.Lambda <Func <T, dynamic> >(anonymousTypeInstance, lambdaParameter);

            var projectedEntity = context.Set <T>()
                                  .AsNoTracking()
                                  .Where(e => e.Id == id)
                                  .Select(lambd11a1)
                                  .Single();

            var mainEntity = Mapper.DynamicMap <T>(projectedEntity);

            mainEntity.Id = id;

            if (selectedSelectProperties.AllProjections.NavigationPropertiesProjections.Count() > 0)
            {
                MaterializeNavigationPropertiesObsolete <T>(mainEntity, projectedEntity, projectedEntityAnonymousType, selectedSelectProperties);
            }

            var alreadytrackedentity = context.ChangeTracker.Entries <T>().Where(e => e.Entity.Id == id).SingleOrDefault();

            if (alreadytrackedentity != null)
            {
                // Remove it from tracking
                alreadytrackedentity.State = EntityState.Detached;
            }
            context.Attach(mainEntity);
            return(mainEntity);
        }
Example #3
0
            public void CanRetrieveByIdUsingTheBuildingQueryCache()
            {
                #region Arrange

                var blog = new Blog();
                blog.Name = Fixture.Create <string>();
                var post = new Post();
                post.Text = Fixture.Create <string>();
                post.Url  = Guid.NewGuid().ToString();

                blog.Posts.AddRange(new List <Post>()
                {
                    post
                });

                using (var uow = UoWFactory.Create())
                {
                    var repository = uow.Create();

                    var createdPost = repository.Add(blog);

                    uow.Commit();
                }

                #endregion Arrange

                #region Act

                long first;
                long second;
                using (var uow = UoWFactory.Create())
                {
                    var repository = uow.Create();

                    Stopwatch stopwatch = Stopwatch.StartNew();
                    ISelectPropertyBuilder <Blog> builder
                        = repository.PropertySelectBuilder <Blog>(blog);

                    var pp = builder
                             .Select(p => p.Name)
                             .Include <Post>(m => m.Posts, p => p.Date, p => p.Text)
                             .Build();

                    stopwatch.Stop();
                    first = stopwatch.ElapsedMilliseconds;

                    var retrievedBlogWithPosts = repository.RetrieveById(blog.Id, pp);
                }

                using (var uow = UoWFactory.Create())
                {
                    var repository = uow.Create();

                    Stopwatch stopwatch = Stopwatch.StartNew();
                    ISelectPropertyBuilder <Blog> builder = repository
                                                            .PropertySelectBuilder <Blog>(blog);

                    var pp = builder
                             .Select(p => p.Name)
                             .Include <Post>(m => m.Posts, p => p.Date, p => p.Text)
                             .Build();

                    second = stopwatch.ElapsedMilliseconds;

                    var retrievedBlogWithPosts = repository.RetrieveById(blog.Id, pp);
                }

                #endregion Act

                #region Assert

                // Assert the latter is faster!

                #endregion Assert
            }