public QueryDeferred(IQueryable query, Expression expression)
#endif
        {
            Expression = expression;

#if EF5 || EF6
            // CREATE query from the deferred expression
            var provider          = ((IQueryable)query).Provider;
            var createQueryMethod = provider.GetType().GetMethod("CreateQuery", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(Expression), typeof(Type) }, null);
            Query = (IQueryable <TResult>)createQueryMethod.Invoke(provider, new object[] { expression, typeof(TResult) });
#elif EFCORE
            if (EFCoreHelper.IsVersion3x)
            {
                // EF Core 3.x
                Query = new EntityQueryable <TResult>((IAsyncQueryProvider)query.Provider, Expression);
            }
            else
            {
                // EF Core 2.x
                Query = new EntityQueryable <TResult>((IAsyncQueryProvider)query.Provider);
                var expressionProperty = typeof(QueryableBase <>).MakeGenericType(typeof(TResult)).GetProperty("Expression", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                expressionProperty.SetValue((QueryableBase <TResult>)Query, expression);
            }
#endif
        }
        public virtual ActionResult MultipleSelector(int page = 1, string parentpath = null, Guid?parentid = null)
        {
            if (!User.Identity.IsAuthenticated && !Metadata.AllowAnonymous)
            {
                return(new HttpStatusCodeResult(403));
            }
            if (!Metadata.ViewRoles.All(t => User.IsInRole(t)))
            {
                return(new HttpStatusCodeResult(403));
            }
            IQueryable <TEntity> queryable = EntityQueryable.Query();

            if (parentpath != null && parentid.HasValue)
            {
                try
                {
                    queryable = EntityQueryable.InParent(queryable, parentpath, parentid.Value);
                }
                catch
                {
                    return(new HttpStatusCodeResult(400));
                }
            }
            var model = new EntityViewModel <TEntity>(EntityQueryable.OrderBy(queryable), page, 10);

            if (Metadata.ParentProperty != null)
            {
                model.Parent = GetParentModel(parentid, 3);
            }
            model.Headers = Metadata.ViewProperties;
            model.UpdateItems();
            return(View(model));
        }
        public virtual ActionResult Edit(Guid id)
        {
            if (!EntityQueryable.Editable())
            {
                return(new HttpStatusCodeResult(403));
            }
            if (!User.Identity.IsAuthenticated && !Metadata.AllowAnonymous)
            {
                return(new HttpStatusCodeResult(403));
            }
            if (!Metadata.EditRoles.All(t => User.IsInRole(t)))
            {
                return(new HttpStatusCodeResult(403));
            }
            TEntity item = EntityQueryable.GetEntity(id);

            if (item == null)
            {
                return(new HttpStatusCodeResult(404));
            }
            var model = new EntityEditModel <TEntity>(item);

            model.Properties = Metadata.EditProperties;
            return(View(model));
        }
Beispiel #4
0
        public virtual async Task <EntityViewer> GetViewer()
        {
            EntityViewModel <TEntity> model = await GetViewModel(EntityQueryable.OrderBy(), 1, 20);

            EntityViewer viewer = new EntityViewer();

            viewer.Model = model;

            return(viewer);
        }
Beispiel #5
0
        public virtual async Task <EntityMultipleSelector> GetMultipleSelector()
        {
            EntityViewModel <TEntity> model = await GetMultipleSelectorModel(EntityQueryable.OrderBy());

            EntityMultipleSelector selector = new EntityMultipleSelector();

            selector.Model = model;

            return(selector);
        }
Beispiel #6
0
 public virtual async Task <bool> Update(TEntity entity)
 {
     if (entity.Index == Guid.Empty)
     {
         return(await EntityQueryable.AddAsync(entity));
     }
     else
     {
         return(await EntityQueryable.EditAsync(entity));
     }
 }
Beispiel #7
0
        private EntityQueryable <TEntity> CreateEntityQueryable()
        {
            var queryable = new EntityQueryable <TEntity>(_context.GetDependencies().QueryProvider);

#pragma warning disable 618
            if (_entityType.FindPrimaryKey() == null)
#pragma warning restore 618
            {
                queryable = (EntityQueryable <TEntity>)queryable.AsNoTracking();
            }

            return(queryable);
        }
        /// <summary>
        /// The starting point for your query. Make sure <typeparamref name="TEntity"/> is available as a <see cref="DbSet{TEntity}"/> on your <see cref="DbContext"/>.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entities.</typeparam>
        /// <param name="contextFactory">The factory which can create the <see cref="DbContext"/>.</param>
        /// <returns></returns>
        public static IQueryable <TEntity> Set <TEntity>(this IDbContextFactory <DbContext> contextFactory)
            where TEntity : class
        {
            if (contextFactory is null)
            {
                throw new System.ArgumentNullException(nameof(contextFactory));
            }

            var query = new EntityQueryable <TEntity>(
                new QueryProvider(new DbContextFactoryQueryContext <DbContext, TEntity>(contextFactory)),
                new EntityType <TEntity>());

            return(query);
        }
        public virtual ActionResult Detail(Guid id)
        {
            if (!Metadata.ViewRoles.All(t => User.IsInRole(t)))
            {
                return(new HttpStatusCodeResult(403));
            }
            TEntity item = EntityQueryable.GetEntity(id);

            if (item == null)
            {
                return(new HttpStatusCodeResult(404));
            }
            var model = new EntityEditModel <TEntity>(item);

            model.Properties = Metadata.DetailProperties;
            return(View(model));
        }
Beispiel #10
0
        public void Setup()
        {
            _mappings = new TestMappingsRepository(new QueryableTests.NamedGraphsPersonMapping());
            _baseUriSelectionPolicy = new Mock <IBaseUriSelectionPolicy>();
            _baseUriSelectionPolicy.Setup(policy => policy.SelectBaseUri(It.IsAny <EntityId>())).Returns(new Uri("http://test/"));
            _entitySource = new Mock <IEntitySource>(MockBehavior.Strict);
            _store        = new Mock <IEntityStore>(MockBehavior.Strict);
            _store.Setup(store => store.AssertEntity(It.IsAny <EntityId>(), It.IsAny <IEnumerable <IEntityQuad> >()));

            _entityContext = new Mock <IEntityContext>(MockBehavior.Strict);
            _entityContext.Setup(context => context.Create <IPerson>(It.IsAny <EntityId>())).Returns((EntityId id) => CreatePersonEntity(id));
            _entityContext.SetupGet(context => context.Mappings).Returns(_mappings);
            _entityContext.SetupGet(context => context.BaseUriSelector).Returns(_baseUriSelectionPolicy.Object);

            _persons     = new EntityQueryable <IPerson>(_entityContext.Object, _entitySource.Object, _store.Object);
            _testQueries = GetTestQueries();
        }
        public void Setup()
        {
            _mappings = new TestMappingsRepository(new QueryableTests.NamedGraphsPersonMapping());
            _baseUriSelectionPolicy = new Mock<IBaseUriSelectionPolicy>();
            _baseUriSelectionPolicy.Setup(policy => policy.SelectBaseUri(It.IsAny<EntityId>())).Returns(new Uri("http://test/"));
            _entitySource = new Mock<IEntitySource>(MockBehavior.Strict);
            _entityStore = new Mock<IEntityStore>(MockBehavior.Strict);
            _entityStore.Setup(store => store.AssertEntity(It.IsAny<EntityId>(), It.IsAny<IEnumerable<EntityQuad>>()));

            _entityContext = new Mock<IEntityContext>(MockBehavior.Strict);
            _entityContext.Setup(context => context.Load<IPerson>(It.IsAny<EntityId>())).Returns((EntityId id) => CreatePersonEntity(id));
            _entityContext.Setup(context => context.Store).Returns(_entityStore.Object);
            _entityContext.SetupGet(context => context.Mappings).Returns(_mappings);
            _entityContext.SetupGet(context => context.BaseUriSelector).Returns(_baseUriSelectionPolicy.Object);

            _persons = new EntityQueryable<IPerson>(_entityContext.Object, _entitySource.Object, _mappings, _baseUriSelectionPolicy.Object);
            _testQueries = GetTestQueries();
        }
Beispiel #12
0
        public static void LINQ_ToString()
        {
            using (var ctx = new WWWingsContext())
            {
                ctx.Log();


                var q1 = from p in ctx.FlightSet
                         where p.FlightNo < 10
                         orderby p.FreeSeats
                         select p;

                EntityQueryable <Flight> q1b = (EntityQueryable <Flight>)q1;

                Console.WriteLine(q1.ToString());  // EF: returns SQL. EFC: returns type :-(
                Console.WriteLine(q1b.ToString()); // EF: returns SQL. EFC: returns type :-(
            }
        }
 public virtual ActionResult Remove(Guid id)
 {
     if (!EntityQueryable.Removeable())
     {
         return(new HttpStatusCodeResult(403));
     }
     if (!Metadata.RemoveRoles.All(t => User.IsInRole(t)))
     {
         return(new HttpStatusCodeResult(403));
     }
     if (EntityQueryable.Remove(id))
     {
         return(new HttpStatusCodeResult(200));
     }
     else
     {
         return(new HttpStatusCodeResult(404));
     }
 }
        public virtual ActionResult Create(Guid?parent = null)
        {
            if (!EntityQueryable.Addable())
            {
                return(new HttpStatusCodeResult(403));
            }
            if (!Metadata.AddRoles.All(t => User.IsInRole(t)))
            {
                return(new HttpStatusCodeResult(403));
            }
            var model = new EntityEditModel <TEntity>(EntityQueryable.Create());

            model.Item.Index = Guid.Empty;
            model.Properties = Metadata.EditProperties;
            if (parent != null && model.Metadata.ParentProperty != null)
            {
                dynamic parentContext = EntityBuilder.GetContext(model.Metadata.ParentProperty.Property.PropertyType);
                object  parentObj     = parentContext.GetEntity(parent.Value);
                model.Metadata.ParentProperty.Property.SetValue(model.Item, parentObj);
            }
            return(View("Edit", model));
        }
Beispiel #15
0
        public static IQueryable <T> FromSql <T>(this DbContext dbContext, RawSqlString sql, params object[] parameters)
        {
            // Argument check
            if (dbContext == null)
            {
                throw new ArgumentNullException(nameof(dbContext));
            }

            // Add new query type if not exists
            dbContext.TryAddQueryType <T>();

            // Get the query provider service instance
            var queryProvider = dbContext.GetDependencies().QueryProvider;

            // Build query source. Actually query source is just used to determine the final result item type.
            var querySource = new EntityQueryable <T>(queryProvider);

            // Build LINQ expression for Entity Framework Core.
            var expression = Expression.Call(null, FromSqlMethod.MakeGenericMethod(typeof(T)), querySource.Expression,
                                             Expression.Constant(sql), Expression.Constant(parameters));

            // Return result
            return(queryProvider.CreateQuery <T>(expression));
        }
Beispiel #16
0
        public async Task ExecuteAsync_UsesSpecifiedContentType()
        {
            // Arrange
            var executor = CreateExecutor();

            var httpContext   = new DefaultHttpContext();
            var actionContext = new ActionContext()
            {
                HttpContext = httpContext
            };

            httpContext.Request.Headers[HeaderNames.Accept] = "application/json"; // This will not be used
            httpContext.Response.ContentType = "application/json";

            IList <Customer>      customers      = new List <Customer>();
            IQueryable <Customer> customersQuery = customers.AsQueryable <Customer>();

            CustomersContext db = new CustomersContext();
            // db.Customers

            Expression expression            = Expression.Constant("abc");
            EntityQueryable <Customer> value = new EntityQueryable <Customer>(db.GetDependencies().QueryProvider, expression);

            var result = new ObjectResult(value)
            {
                ContentTypes = { "application/json", },
            };

            result.Formatters.Add(new TestJsonOutputFormatter());

            // Act
            await executor.ExecuteAsync(actionContext, result);

            // Assert
            // MediaTypeAssert.Equal("text/xml; charset=utf-8", httpContext.Response.ContentType);
        }
 public ExpressionTranslater(Expression root, EntityQueryable <T> entityQuery)
 {
     this.root        = root;
     this.EntityQuery = entityQuery;
 }
        /// <summary>Executes the given expression.</summary>
        /// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
        /// <typeparam name="TResult">Type of the result.</typeparam>
        /// <param name="expression">The expression to execute.</param>
        /// <returns>The object returned by the execution of the expression.</returns>
        public TResult Execute <TResult>(Expression expression)
        {
            var methodCall = expression as MethodCallExpression;

            if (methodCall == null)
            {
                throw new Exception(ExceptionMessage.GeneralException);
            }

            if (methodCall.Method.Name == "All" ||
                methodCall.Method.Name == "Any" ||
                methodCall.Method.Name == "Average" ||
                methodCall.Method.Name == "Contains" ||
                methodCall.Method.Name == "Count" ||
                methodCall.Method.Name == "LongCount" ||
                methodCall.Method.Name == "Max" ||
                methodCall.Method.Name == "Min" ||
                methodCall.Method.Name == "SequenceEqual" ||
                methodCall.Method.Name == "Sum")
            {
                return(OriginalProvider.Execute <TResult>(expression));
            }

            QueryIncludeOptimizedIncludeSubPath.RemoveLazyChild(CurrentQueryable);

            var currentQuery  = CurrentQueryable;
            var currentMethod = methodCall.Method.GetGenericMethodDefinition();

            // CHECK if the internal expression can be supported
            var isExpressionSupported = false;

            var firstExpression = methodCall.Arguments.FirstOrDefault(x => x.Type.IsSubclassOf(typeof(Expression)));

            if (firstExpression != null && methodCall.Arguments.Count == 2)
            {
                var quoteExpression  = ((UnaryExpression)firstExpression).Operand;
                var lambdaExpression = quoteExpression as LambdaExpression;
                if (lambdaExpression != null)
                {
                    if (lambdaExpression.Type == typeof(Func <,>).MakeGenericType(currentQuery.ElementType, typeof(bool)))
                    {
                        var method        = typeof(Queryable).GetMethods().First(x => x.Name == "Where" && x.GetParameters()[1].ParameterType.GetGenericArguments()[0].GetGenericArguments().Length == 2);
                        var methodGeneric = method.MakeGenericMethod(currentQuery.ElementType);
                        currentQuery          = (QueryIncludeOptimizedParentQueryable <T>)methodGeneric.Invoke(null, new object[] { currentQuery, lambdaExpression });
                        currentMethod         = typeof(Queryable).GetMethods().FirstOrDefault(x => x.Name == currentMethod.Name && x.GetParameters().Length == 1);
                        isExpressionSupported = currentMethod != null;
                    }
                }
            }

            if (firstExpression != null && !isExpressionSupported)
            {
                throw new Exception(ExceptionMessage.QueryIncludeOptimized_ArgumentExpression);
            }

            // CREATE the new query by selecting included entities in an anonymous type
            var newQuery = currentQuery;

            // REPLACE the first argument with the new query expression
            var arguments = methodCall.Arguments.ToList();

            arguments[0] = newQuery.Expression;

            // REMOVE the last argument if a "Predicate" method was previously used
            if (firstExpression != null)
            {
                arguments.RemoveAt(1);
            }

            // RESOLE parent queries using .FutureValue();
#if EFCORE_3X
            var immediateQuery = new EntityQueryable <TResult>((IAsyncQueryProvider)OriginalProvider, expression);
#elif EF5 || EF6
            var objectQuery = CurrentQueryable.OriginalQueryable.GetObjectQuery();

            // GET provider
            //  because IQueryable.Provider call : ObjectQueryProvider and now that work for EF5
            var objectQueryProviderField = typeof(ObjectQuery).GetProperty("System.Linq.IQueryable.Provider", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            var provider = (IQueryProvider)objectQueryProviderField.GetValue(objectQuery, null);

            // CREATE query from the expression
            var createQueryMethod = provider.GetType().GetMethod("CreateQuery", BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(Expression) }, null);
            createQueryMethod = createQueryMethod.MakeGenericMethod(typeof(TResult));
            var immediateQuery = (ObjectQuery <T>)createQueryMethod.Invoke(provider, new object[] { expression });
#endif

            object value = null;

            if (QueryIncludeOptimizedManager.AllowQueryBatch)
            {
                var futureValue = immediateQuery.FutureValue();

                // RESOLVE child queries using .Future()
                {
                    // MODIFY query if necessary
#if EF5 || EF6
                    var objectContext = CurrentQueryable.OriginalQueryable.GetObjectQuery().Context;
                    var keyMembers    = objectContext.GetEntitySet <T>().ElementType.KeyMembers;
                    var keyNames      = ((IEnumerable <EdmMember>)keyMembers).Select(x => x.Name).ToArray();
#elif EFCORE
                    var context = currentQuery.OriginalQueryable.GetDbContext();

                    var keyNames = context.Model.FindEntityType(typeof(TResult).DisplayName(true))
                                   .GetKeys().ToList()[0]
                                   .Properties.Select(x => x.Name).ToArray();
#endif

                    var currentNewQuery = methodCall.Method.Name == "First" || methodCall.Method.Name == "FirstOrDefault" ?
                                          currentQuery.AddToRootOrAppendOrderBy(keyNames).Take(1) :
                                          methodCall.Method.Name == "Last" || methodCall.Method.Name == "LastOrDefault" ?
                                          currentQuery.AddToRootOrAppendOrderBy(keyNames).Reverse().Take(1) :
                                          currentQuery;

                    currentQuery.CreateQueryable(currentNewQuery);
                }

                value = futureValue.Value;
            }
            else
            {
#if EFCORE_3X
                value = immediateQuery.FutureValue().Value;
#else
                value = immediateQuery.Execute(objectQuery.MergeOption).FirstOrDefault();
#endif

                // RESOLVE child queries using .Future()
                {
                    // MODIFY query if necessary
#if EF5 || EF6
                    var objectContext = CurrentQueryable.OriginalQueryable.GetObjectQuery().Context;
                    var keyMembers    = ((dynamic)objectContext).CreateObjectSet <T>().EntitySet.ElementType.KeyMembers;
                    var keyNames      = ((IEnumerable <EdmMember>)keyMembers).Select(x => x.Name).ToArray();
#elif EFCORE
                    var context = currentQuery.OriginalQueryable.GetDbContext();

                    var keyNames = context.Model.FindEntityType(typeof(TResult).DisplayName(true))
                                   .GetKeys().ToList()[0]
                                   .Properties.Select(x => x.Name).ToArray();
#endif

                    var currentNewQuery = methodCall.Method.Name == "First" || methodCall.Method.Name == "FirstOrDefault" ?
                                          currentQuery.AddToRootOrAppendOrderBy(keyNames).Take(1) :
                                          methodCall.Method.Name == "Last" || methodCall.Method.Name == "LastOrDefault" ?
                                          currentQuery.AddToRootOrAppendOrderBy(keyNames).Reverse().Take(1) :
                                          currentQuery;

                    currentQuery.CreateQueryable(currentNewQuery);
                }
            }


            // EXECUTE the new expression
            //var value = QueryIncludeOptimizedManager.AllowQueryBatch ? immediateQuery.FutureValue().Value : immediateQuery.FirstOrDefault();

            // CHECK if a value has been returned
            if (value == null)
            {
                return((TResult)(object)null);
            }

#if EF6
            // FIX lazy loading
            QueryIncludeOptimizedLazyLoading.SetLazyLoaded(value, CurrentQueryable.Childs);
#endif

            // FIX null collection
            QueryIncludeOptimizedNullCollection.NullCollectionToEmpty(value, CurrentQueryable.Childs);

#if EF5 || EF6
            return((TResult)(object)value);
#elif EFCORE
            return((TResult)value);
#endif
        }
Beispiel #19
0
        protected virtual Task <EntityViewModel <TEntity> > GetViewModel(IQueryable <TEntity> queryable, int page, int size)
        {
            return(Task.Run <EntityViewModel <TEntity> >(() =>
            {
                EntityViewModel <TEntity> model = new EntityViewModel <TEntity>(queryable, page, size);
                model.Headers = Metadata.ViewProperties;

                EntityViewButton createButton = new EntityViewButton();
                createButton.Name = "Create";
                createButton.GetInvokeDelegate = new EntityViewButtonCommandDelegate(viewer =>
                {
                    return new Task(async() =>
                    {
                        var item = EntityQueryable.Create();
                        bool?result = null;
                        await viewer.Dispatcher.Invoke(async() =>
                        {
                            viewer.IsLoading = true;
                            var editor = await GetEditor(item);
                            result = editor.ShowDialog();
                        });
                        if (result == true)
                        {
                            await Update(item);
                            model.UpdateTotalPage();
                            model.Items = model.Items.Concat(new TEntity[] { item }).ToArray();
                        }
                        viewer.Dispatcher.Invoke(() =>
                        {
                            viewer.IsLoading = false;
                        });
                    });
                });
                model.ViewButtons = new IViewButton[] { createButton };

                EntityItemButton editButton = new EntityItemButton();
                editButton.Name = "Edit";
                editButton.GetInvokeDelegate = new EntityItemButtonCommandDelegate((viewer, entity) =>
                {
                    return new Task(async() =>
                    {
                        var item = (TEntity)entity;
                        bool?result = null;
                        await viewer.Dispatcher.Invoke(async() =>
                        {
                            viewer.IsLoading = true;
                            var editor = await GetEditor(item);
                            result = editor.ShowDialog();
                        });
                        if (result == true)
                        {
                            await Update(item);
                        }
                        viewer.Dispatcher.Invoke(() =>
                        {
                            viewer.IsLoading = false;
                        });
                    });
                });
                EntityItemButton removeButton = new EntityItemButton();
                removeButton.Name = "Remove";
                removeButton.GetInvokeDelegate = new EntityItemButtonCommandDelegate((viewer, entity) =>
                {
                    return new Task(async() =>
                    {
                        viewer.Dispatcher.Invoke(() =>
                        {
                            viewer.IsLoading = true;
                        });
                        await EntityQueryable.RemoveAsync(entity.Index);
                        model.Items = await EntityQueryable.ToArrayAsync(queryable.Skip(page).Take(size));
                        viewer.Dispatcher.Invoke(() =>
                        {
                            viewer.IsLoading = false;
                        });
                    });
                });
                model.ItemButtons = new IEntityViewButton[] { editButton, removeButton };

                return model;
            }));
        }
Beispiel #20
0
 IEnumerator IEnumerable.GetEnumerator() => EntityQueryable.GetEnumerator();
Beispiel #21
0
 IEnumerator <TEntity> IEnumerable <TEntity> .GetEnumerator() => EntityQueryable.GetEnumerator();
Beispiel #22
0
        /// <summary>Executes the given expression.</summary>
        /// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
        /// <typeparam name="TResult">Type of the result.</typeparam>
        /// <param name="expression">The expression to execute.</param>
        /// <returns>The object returned by the execution of the expression.</returns>
        public TResult Execute <TResult>(Expression expression)
        {
            var methodCall = expression as MethodCallExpression;

            if (methodCall == null)
            {
                throw new Exception(ExceptionMessage.GeneralException);
            }

            var currentQuery  = CurrentQueryable;
            var currentMethod = methodCall.Method.GetGenericMethodDefinition();

            // CHECK if the internal expression can be supported]
            var isExpressionSupported = false;

            var firstExpression = methodCall.Arguments.FirstOrDefault(x => x.Type.IsSubclassOf(typeof(Expression)));

            if (firstExpression != null && methodCall.Arguments.Count == 2)
            {
                var quoteExpression  = ((UnaryExpression)firstExpression).Operand;
                var lambdaExpression = quoteExpression as LambdaExpression;
                if (lambdaExpression != null)
                {
                    if (lambdaExpression.Type == typeof(Func <,>).MakeGenericType(currentQuery.ElementType, typeof(bool)))
                    {
                        var method        = typeof(Queryable).GetMethods().First(x => x.Name == "Where" && x.GetParameters()[1].ParameterType.GetGenericArguments()[0].GetGenericArguments().Length == 2);
                        var methodGeneric = method.MakeGenericMethod(currentQuery.ElementType);
                        currentQuery          = (QueryIncludeOptimizedParentQueryable <T>)methodGeneric.Invoke(null, new object[] { currentQuery, lambdaExpression });
                        currentMethod         = typeof(Queryable).GetMethods().FirstOrDefault(x => x.Name == currentMethod.Name && x.GetParameters().Length == 1);
                        isExpressionSupported = currentMethod != null;
                    }
                }
            }

            if (firstExpression != null && !isExpressionSupported)
            {
                throw new Exception(ExceptionMessage.QueryIncludeOptimized_ArgumentExpression);
            }

            // CREATE the new query by selecting included entities in an anonymous type
            var newQuery = currentQuery;

            // REPLACE the first argument with the new query expression
            var arguments = methodCall.Arguments.ToList();

            arguments[0] = newQuery.Expression;

            // REMOVE the last argument if a "Predicate" method was previously used
            if (firstExpression != null)
            {
                arguments.RemoveAt(1);
            }

            // RESOLVE child queries using .Future()
            {
                // MODIFY query if necessary
#if EF5 || EF6
                var objectContext = CurrentQueryable.OriginalQueryable.GetObjectQuery().Context;
                var keyMembers    = ((dynamic)objectContext).CreateObjectSet <T>().EntitySet.ElementType.KeyMembers;
                var keyNames      = ((IEnumerable <EdmMember>)keyMembers).Select(x => x.Name).ToArray();
#elif EF7
                var context = currentQuery.OriginalQueryable.GetDbContext();

                var keyNames = context.Model.FindEntityType(typeof(TResult).DisplayName(true))
                               .GetKeys().ToList()[0]
                               .Properties.Select(x => x.Name).ToArray();
#endif

                var currentNewQuery = methodCall.Method.Name == "First" || methodCall.Method.Name == "FirstOrDefault" ?
                                      currentQuery.AddToRootOrAppendOrderBy(keyNames).Take(1) :
                                      methodCall.Method.Name == "Last" || methodCall.Method.Name == "LastOrDefault" ?
                                      currentQuery.AddToRootOrAppendOrderBy(keyNames).Reverse().Take(1) :
                                      currentQuery;

                currentQuery.CreateQueryable(currentNewQuery);
            }

            // RESOLE parent queries using .FutureValue();
#if EF5 || EF6
            var objectQuery = CurrentQueryable.OriginalQueryable.GetObjectQuery();

            // GET provider
            var objectQueryProviderField = typeof(ObjectQuery).GetField("_provider", BindingFlags.NonPublic | BindingFlags.Instance);
            var provider = (IQueryProvider)objectQueryProviderField.GetValue(objectQuery);

            // CREATE query from the expression
            var createQueryMethod = provider.GetType().GetMethod("CreateQuery", BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(Expression) }, null);
            createQueryMethod = createQueryMethod.MakeGenericMethod(typeof(TResult));
            var immediateQuery = (ObjectQuery <T>)createQueryMethod.Invoke(provider, new object[] { expression });
#elif EF7
            var immediateQuery     = new EntityQueryable <TResult>((IAsyncQueryProvider)OriginalProvider);
            var expressionProperty = typeof(QueryableBase <>).MakeGenericType(typeof(TResult)).GetProperty("Expression", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            expressionProperty.SetValue(immediateQuery, expression);
#endif

            // EXECUTE the new expression
            var futureValue = immediateQuery.FutureValue();

            var value = futureValue.Value;

            // CHECK if a value has been returned
            if (value == null)
            {
                return((TResult)(object)null);
            }

#if EF5 || EF6
            return((TResult)(object)value);
#elif EF7
            return((TResult)value);
#endif
        }
Beispiel #23
0
 public DbSet([NotNull] DbContext context)
     : base(Check.NotNull(context, "context"))
 {
     _entityQueryable
         = new EntityQueryable <TEntity>(new EntityQueryExecutor(context));
 }
 /// <summary>
 ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
 ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
 ///     any release. You should only use it directly in your code with extreme caution and knowing that
 ///     doing so can result in application failures when updating to a new Entity Framework Core release.
 /// </summary>
 IAsyncEnumerator <TEntity> IAsyncEnumerable <TEntity> .GetAsyncEnumerator(CancellationToken cancellationToken)
 => EntityQueryable.GetAsyncEnumerator(cancellationToken);
        public virtual ActionResult Update(Guid id)
        {
            TEntity entity;

            if (id == Guid.Empty)
            {
                if (!EntityQueryable.Addable())
                {
                    return(new HttpStatusCodeResult(403));
                }
                if (!Metadata.AddRoles.All(t => User.IsInRole(t)))
                {
                    return(new HttpStatusCodeResult(403));
                }
                entity = EntityQueryable.Create();
            }
            else
            {
                if (!EntityQueryable.Editable())
                {
                    return(new HttpStatusCodeResult(403));
                }
                if (!Metadata.EditRoles.All(t => User.IsInRole(t)))
                {
                    return(new HttpStatusCodeResult(403));
                }
                entity = EntityQueryable.GetEntity(id);
                if (entity == null)
                {
                    return(new HttpStatusCodeResult(404));
                }
            }
            var properties = Metadata.Properties.Where(t => !t.IsHiddenOnEdit).ToArray();

            for (int i = 0; i < properties.Length; i++)
            {
                PropertyMetadata propertyMetadata = properties[i];
                if (propertyMetadata.Type == ComponentModel.DataAnnotations.CustomDataType.File || propertyMetadata.Type == ComponentModel.DataAnnotations.CustomDataType.Image)
                {
                    #region File Path Value
                    if (!Request.Files.AllKeys.Contains(propertyMetadata.Property.Name))
                    {
                        continue;
                    }
                    if (!(this is IFileController <TEntity>))
                    {
                        throw new NotSupportedException("Controller doesn't support upload file.");
                    }
                    ((IFileController <TEntity>) this).SaveFileToProperty(entity, propertyMetadata, Request.Files[propertyMetadata.Property.Name]);
                    #endregion
                }
                else
                {
                    #region Property Value
                    if (!Request.Form.AllKeys.Contains(propertyMetadata.Property.Name))
                    {
                        if (id == Guid.Empty && propertyMetadata.IsRequired)
                        {
                            Response.StatusCode = 400;
                            return(Content(propertyMetadata.Name + "为必填项"));
                        }
                        continue;
                    }
                    string originValue = Request.Form[propertyMetadata.Property.Name];
                    if (string.IsNullOrEmpty(originValue) && propertyMetadata.Property.PropertyType != typeof(string) && propertyMetadata.IsRequired)
                    {
                        Response.StatusCode = 400;
                        return(Content(propertyMetadata.Name + "为必填项"));
                    }
                    //Type type = propertyMetadata.Property.PropertyType;
                    //if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
                    //    type = type.GetGenericArguments()[0];
                    TypeConverter converter = EntityValueConverter.GetConverter(propertyMetadata);
                    if (converter == null)
                    {
                        if (propertyMetadata.Property.PropertyType.IsGenericType && propertyMetadata.Property.PropertyType.GetGenericTypeDefinition() == typeof(ICollection <>))
                        {
                            converter = new Converter.CollectionConverter();
                        }
                        else if (propertyMetadata.Property.PropertyType.IsEnum)
                        {
                            converter = new EnumConverter(propertyMetadata.Property.PropertyType);
                        }
                        else
                        if (propertyMetadata.Type != ComponentModel.DataAnnotations.CustomDataType.Password)
                        {
                            throw new NotSupportedException("Type of \"" + propertyMetadata.Property.PropertyType.Name + "\" converter not found.");
                        }
                    }
                    if (propertyMetadata.Type == ComponentModel.DataAnnotations.CustomDataType.Password && entity is IPassword)
                    {
                        object v = propertyMetadata.Property.GetValue(entity);
                        if (v == null || originValue != v.ToString())
                        {
                            ((IPassword)entity).SetPassword(originValue);
                        }
                    }
                    else
                    {
                        EntityValueConverterContext context = new EntityValueConverterContext(EntityBuilder.DescriptorContext, propertyMetadata);
                        object value = converter.ConvertFrom(context, null, originValue);
                        if (converter.GetType() == typeof(Converter.CollectionConverter))
                        {
                            object collection = propertyMetadata.Property.GetValue(entity);
                            ((dynamic)collection).Clear();
                            var      addMethod = collection.GetType().GetMethod("Add");
                            object[] array     = (object[])value;
                            for (int a = 0; a < array.Length; a++)
                            {
                                addMethod.Invoke(collection, new object[] { array[a] });
                            }
                        }
                        else
                        {
                            propertyMetadata.Property.SetValue(entity, value);
                        }
                    }
                    #endregion
                }
            }
            var validateResult = entity.Validate(null);
            if (validateResult.Count() != 0)
            {
                Response.StatusCode = 400;
                return(Content(new string(validateResult.SelectMany(t => t.ErrorMessage += "/r/n").ToArray())));
            }
            bool result;
            if (id == Guid.Empty)
            {
                result = EntityQueryable.Add(entity);
            }
            else
            {
                result = EntityQueryable.Edit(entity);
            }
            if (result)
            {
                return(Content(entity.Index.ToString()));
            }
            else
            {
                Response.StatusCode = 400;
                return(Content("未知"));
            }
        }
        private MainFromClause CreateWithEntityQueryable <T>()
        {
            var queryable = new EntityQueryable <T>(new EntityQueryExecutor(Mock.Of <DbContext>()));

            return(new MainFromClause("s", typeof(T), Expression.Constant(queryable)));
        }
Beispiel #27
0
        protected virtual async Task <EntityEditModel <TEntity> > GetEditModel(Guid id)
        {
            var item = await EntityQueryable.GetEntityAsync(id);

            return(await GetEditModel(item));
        }
Beispiel #28
0
 public DbQueryProvider(EntityQueryable <T> entityQuery)
     : base()
 {
     this.entityQuery = entityQuery;
 }
Beispiel #29
0
        /// <summary>Executes the given expression.</summary>
        /// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
        /// <typeparam name="TResult">Type of the result.</typeparam>
        /// <param name="expression">The expression to execute.</param>
        /// <returns>The object returned by the execution of the expression.</returns>
        public TResult Execute <TResult>(Expression expression)
        {
            var methodCall = expression as MethodCallExpression;

            if (methodCall == null)
            {
                throw new Exception(ExceptionMessage.GeneralException);
            }

            if (methodCall.Method.Name == "All" ||
                methodCall.Method.Name == "Any" ||
                methodCall.Method.Name == "Average" ||
                methodCall.Method.Name == "Contains" ||
                methodCall.Method.Name == "Count" ||
                methodCall.Method.Name == "LongCount" ||
                methodCall.Method.Name == "Max" ||
                methodCall.Method.Name == "Min" ||
                methodCall.Method.Name == "SequenceEqual" ||
                methodCall.Method.Name == "Sum")
            {
                return(OriginalProvider.Execute <TResult>(expression));
            }

            QueryIncludeFilterIncludeSubPath.RemoveLazyChild(CurrentQueryable);

            var currentQuery  = CurrentQueryable;
            var currentMethod = methodCall.Method.GetGenericMethodDefinition();

            // CHECK if the internal expression can be supported
            var isExpressionSupported = false;

            var firstExpression = methodCall.Arguments.FirstOrDefault(x => x.Type.IsSubclassOf(typeof(Expression)));

            if (firstExpression != null && methodCall.Arguments.Count == 2)
            {
                var quoteExpression  = ((UnaryExpression)firstExpression).Operand;
                var lambdaExpression = quoteExpression as LambdaExpression;
                if (lambdaExpression != null)
                {
                    if (lambdaExpression.Type == typeof(Func <,>).MakeGenericType(currentQuery.ElementType, typeof(bool)))
                    {
                        var method        = typeof(Queryable).GetMethods().First(x => x.Name == "Where" && x.GetParameters()[1].ParameterType.GetGenericArguments()[0].GetGenericArguments().Length == 2);
                        var methodGeneric = method.MakeGenericMethod(currentQuery.ElementType);
                        currentQuery          = (QueryIncludeFilterParentQueryable <T>)methodGeneric.Invoke(null, new object[] { currentQuery, lambdaExpression });
                        currentMethod         = typeof(Queryable).GetMethods().FirstOrDefault(x => x.Name == currentMethod.Name && x.GetParameters().Length == 1);
                        isExpressionSupported = currentMethod != null;
                    }
                }
            }

            if (firstExpression != null && !isExpressionSupported)
            {
                throw new Exception(ExceptionMessage.QueryIncludeFilter_ArgumentExpression);
            }

            // CREATE the new query by selecting included entities in an anonymous type
            var newQuery = currentQuery;

            // REPLACE the first argument with the new query expression
            var arguments = methodCall.Arguments.ToList();

            arguments[0] = newQuery.Expression;

            // REMOVE the last argument if a "Predicate" method was previously used
            if (firstExpression != null)
            {
                arguments.RemoveAt(1);
            }

#if EFCORE_3X
            // RESOLE parent queries using .FutureValue();
            var immediateQuery = new EntityQueryable <TResult>((IAsyncQueryProvider)OriginalProvider, expression);
#else
            // RESOLE parent queries using .FutureValue();
            var immediateQuery     = new EntityQueryable <TResult>((IAsyncQueryProvider)OriginalProvider);
            var expressionProperty = typeof(QueryableBase <>).MakeGenericType(typeof(TResult)).GetProperty("Expression", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            expressionProperty.SetValue(immediateQuery, expression);
#endif

            object value = null;

            DbContext context = null;

            if (currentQuery.OriginalQueryable.IsInMemoryQueryContext())
            {
                context = currentQuery.OriginalQueryable.GetInMemoryContext();
            }
            else
            {
                // MODIFY query if necessary
                context = currentQuery.OriginalQueryable.GetDbContext();
            }

            if (QueryIncludeFilterManager.AllowQueryBatch)
            {
                var futureValue = immediateQuery.FutureValue();

                // RESOLVE child queries using .Future()
                {
                    // MODIFY query if necessary

                    var keyNames = context.Model.FindEntityType(typeof(TResult).DisplayName(true))
                                   .GetKeys().ToList()[0]
                                   .Properties.Select(x => x.Name).ToArray();

                    var currentNewQuery = methodCall.Method.Name == "First" || methodCall.Method.Name == "FirstOrDefault" ? currentQuery.AddToRootOrAppendOrderBy(keyNames).Take(1) :
                                          methodCall.Method.Name == "Last" || methodCall.Method.Name == "LastOrDefault" ? currentQuery.AddToRootOrAppendOrderBy(keyNames).Reverse().Take(1) :
                                          currentQuery;

                    currentQuery.CreateQueryable(currentNewQuery);
                }

                value = futureValue.Value;
            }
            else
            {
                // TODO: Find a better way
                value = immediateQuery.FutureValue().Value;
                //value = immediateQuery.Execute(objectQuery.MergeOption).FirstOrDefault();

                // RESOLVE child queries using .Future()
                {
                    // MODIFY query if necessary

                    var keyNames = context.Model.FindEntityType(typeof(TResult).DisplayName(true))
                                   .GetKeys().ToList()[0]
                                   .Properties.Select(x => x.Name).ToArray();

                    var currentNewQuery = methodCall.Method.Name == "First" || methodCall.Method.Name == "FirstOrDefault" ?
                                          currentQuery.AddToRootOrAppendOrderBy(keyNames).Take(1) :
                                          methodCall.Method.Name == "Last" || methodCall.Method.Name == "LastOrDefault" ?
                                          currentQuery.AddToRootOrAppendOrderBy(keyNames).Reverse().Take(1) :
                                          currentQuery;

                    currentQuery.CreateQueryable(currentNewQuery);
                }
            }


            // EXECUTE the new expression
            //var value = QueryIncludeFilterManager.AllowQueryBatch ? immediateQuery.FutureValue().Value : immediateQuery.FirstOrDefault();

            // CHECK if a value has been returned
            if (value == null)
            {
                return((TResult)(object)null);
            }

            // FIX null collection
            QueryIncludeFilterNullCollection.NullCollectionToEmpty(value, CurrentQueryable.Childs);

            return((TResult)value);
        }