/// <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); }
public bool HasQueryMethod() { return(ExpressionQuery != null || !ExpressionQueryMethod.IsNullOrEmpty()); }
/// <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); }