Ejemplo n.º 1
0
        /// <summary>
        /// Loads query method expression from <see cref="ExpressionQueryMethod"/> member.
        /// </summary>
        /// <param name="parentType">Type of object that declares association</param>
        /// <param name="objectType">Type of object associated with query method expression</param>
        /// <returns><c>null</c> of association has no custom query method expression or query method expression, specified
        /// by <see cref="ExpressionQueryMethod"/> member.</returns>
        public LambdaExpression?GetQueryMethod(Type parentType, Type objectType)
        {
            if (ExpressionQuery == null && ExpressionQueryMethod.IsNullOrEmpty())
            {
                return(null);
            }

            Expression queryExpression;

            var type = MemberInfo.DeclaringType;

            if (type == null)
            {
                throw new ArgumentException($"Member '{MemberInfo.Name}' has no declaring type");
            }

            if (!ExpressionQueryMethod.IsNullOrEmpty())
            {
                queryExpression = type.GetExpressionFromExpressionMember <Expression>(ExpressionQueryMethod);
            }
            else
            {
                queryExpression = ExpressionQuery !;
            }

            var lambda = queryExpression as LambdaExpression;

            if (lambda == null || lambda.Parameters.Count != 2)
            {
                if (!string.IsNullOrEmpty(ExpressionQueryMethod))
                {
                    throw new LinqToDBException(
                              $"Invalid predicate expression in {type.Name}.{ExpressionQueryMethod}. Expected: Expression<Func<{parentType.Name}, IDataContext, IQueryable<{objectType.Name}>>>");
                }
                else
                {
                    throw new LinqToDBException(
                              $"Invalid predicate expression in {type.Name}. Expected: Expression<Func<{parentType.Name}, IDataContext, IQueryable<{objectType.Name}>>>");
                }
            }

            if (!lambda.Parameters[0].Type.IsSameOrParentOf(parentType))
            {
                throw new LinqToDBException($"First parameter of expression predicate should be '{parentType.Name}'");
            }

            if (typeof(IDataContext) != lambda.Parameters[1].Type)
            {
                throw new LinqToDBException("Second parameter of expression predicate should be 'IDataContext'");
            }

            if (!(typeof(IQueryable <>).IsSameOrParentOf(lambda.ReturnType) &&
                  lambda.ReturnType.GetGenericArguments()[0].IsSameOrParentOf(objectType)))
            {
                throw new LinqToDBException("Result type of expression predicate should be 'IQueryable<{objectType.Name}>'");
            }

            return(lambda);
        }
Ejemplo n.º 2
0
 public bool HasQueryMethod()
 {
     return(ExpressionQuery != null || !ExpressionQueryMethod.IsNullOrEmpty());
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Loads query method expression from <see cref="ExpressionQueryMethod"/> member.
        /// </summary>
        /// <param name="parentType">Type of object that declares association</param>
        /// <param name="objectType">Type of object associated with query method expression</param>
        /// <returns><c>null</c> of association has no custom query method expression or query method expression, specified
        /// by <see cref="ExpressionQueryMethod"/> member.</returns>
        public LambdaExpression GetQueryMethod(Type parentType, Type objectType)
        {
            if (ExpressionQuery == null && ExpressionQueryMethod.IsNullOrEmpty())
            {
                return(null);
            }

            Expression queryExpression = null;

            var type = MemberInfo.DeclaringType;

            if (type == null)
            {
                throw new ArgumentException($"Member '{MemberInfo.Name}' has no declaring type");
            }

            if (!string.IsNullOrEmpty(ExpressionQueryMethod))
            {
                var members = type.GetStaticMembersEx(ExpressionQueryMethod);

                if (members.Length == 0)
                {
                    throw new LinqToDBException($"Static member '{ExpressionQueryMethod}' for type '{type.Name}' not found");
                }

                if (members.Length > 1)
                {
                    throw new LinqToDBException($"Ambiguous members '{ExpressionQueryMethod}' for type '{type.Name}' has been found");
                }

                var propInfo = members[0] as PropertyInfo;

                if (propInfo != null)
                {
                    var value = propInfo.GetValue(null, null);
                    if (value == null)
                    {
                        return(null);
                    }

                    queryExpression = value as Expression;
                    if (queryExpression == null)
                    {
                        throw new LinqToDBException($"Property '{ExpressionQueryMethod}' for type '{type.Name}' should return expression");
                    }
                }
                else
                {
                    var method = members[0] as MethodInfo;
                    if (method != null)
                    {
                        if (method.GetParameters().Length > 0)
                        {
                            throw new LinqToDBException($"Method '{ExpressionQueryMethod}' for type '{type.Name}' should have no parameters");
                        }
                        var value = method.Invoke(null, Array <object> .Empty);
                        if (value == null)
                        {
                            return(null);
                        }

                        queryExpression = value as Expression;
                        if (queryExpression == null)
                        {
                            throw new LinqToDBException($"Method '{ExpressionQueryMethod}' for type '{type.Name}' should return expression");
                        }
                    }
                }
                if (queryExpression == null)
                {
                    throw new LinqToDBException(
                              $"Member '{ExpressionQueryMethod}' for type '{type.Name}' should be static property or method");
                }
            }
            else
            {
                queryExpression = ExpressionQuery;
            }

            var lambda = queryExpression as LambdaExpression;

            if (lambda == null || lambda.Parameters.Count != 2)
            {
                if (!string.IsNullOrEmpty(ExpressionQueryMethod))
                {
                    throw new LinqToDBException(
                              $"Invalid predicate expression in {type.Name}.{ExpressionQueryMethod}. Expected: Expression<Func<{parentType.Name}, IDataContext, IQueryable<{objectType.Name}>>>");
                }
                else
                {
                    throw new LinqToDBException(
                              $"Invalid predicate expression in {type.Name}. Expected: Expression<Func<{parentType.Name}, IDataContext, IQueryable<{objectType.Name}>>>");
                }
            }

            if (!lambda.Parameters[0].Type.IsSameOrParentOf(parentType))
            {
                throw new LinqToDBException($"First parameter of expression predicate should be '{parentType.Name}'");
            }

            if (typeof(IDataContext) != lambda.Parameters[1].Type)
            {
                throw new LinqToDBException("Second parameter of expression predicate should be 'IDataContext'");
            }

            if (!(typeof(IQueryable <>).IsSameOrParentOf(lambda.ReturnType) &&
                  lambda.ReturnType.GetGenericArguments()[0].IsSameOrParentOf(objectType)))
            {
                throw new LinqToDBException("Result type of expression predicate should be 'IQueryable<{objectType.Name}>'");
            }

            return(lambda);
        }