/// <summary>
        /// Validates the given lambda to see if it is a valid LINQ to Entities expression
        /// </summary>
        /// <param name="lambda">The lambda syntax node</param>
        /// <param name="rootQueryableType">The type of the IQueryable instance where a known LINQ operator is invoked on with this lambda</param>
        /// <param name="context">The analysis context</param>
        /// <param name="efContext">The EF-specific view of the semantic model</param>
        /// <param name="treatAsWarning">If true, instructs any diagnostic reports to be flagged as warnings instead of errors. This is normally true when the analyzer cannot fully determine that the LINQ expression is made against an actual DbSet</param>
        public static void ValidateLinqToEntitiesExpression(LambdaExpressionSyntax lambda, EFCodeFirstClassInfo rootQueryableType, SyntaxNodeAnalysisContext context, EFUsageContext efContext, bool treatAsWarning = false)
        {
            var descendants    = lambda.DescendantNodes();
            var parameterNodes = ContextualLinqParameter.BuildContext(descendants.OfType <ParameterSyntax>(), context, efContext);

            ValidateLinqToEntitiesUsageInSyntaxNodes(descendants, rootQueryableType, context, efContext, parameterNodes, treatAsWarning);
        }
        public static Dictionary <string, ContextualLinqParameter> BuildContext(QueryExpressionSyntax query, SyntaxNodeAnalysisContext context, EFUsageContext efContext)
        {
            var cparams = new Dictionary <string, ContextualLinqParameter>();

            //From x
            var fromExpr = query.FromClause.Identifier;
            //in <expr>
            var    inExpr = query.FromClause.Expression;
            string name   = fromExpr.ValueText;

            var memberExpr = inExpr as MemberAccessExpressionSyntax;

            if (memberExpr != null)
            {
                EFCodeFirstClassInfo cls;
                if (LinqExpressionValidator.MemberAccessIsAccessingDbContext(memberExpr, context, efContext, out cls))
                {
                    cparams[name] = new ContextualLinqParameter(name, cls);
                }
            }

            //Still not set, just set as a contextual parameter with no known type
            if (!cparams.ContainsKey(name))
            {
                cparams[name] = new ContextualLinqParameter(name);
            }

            return(cparams);
        }
        public static Dictionary <string, ContextualLinqParameter> BuildContext(IEnumerable <ParameterSyntax> parameters, SyntaxNodeAnalysisContext context, EFUsageContext efContext)
        {
            var cparams = new Dictionary <string, ContextualLinqParameter>();

            foreach (var p in parameters)
            {
                string name = p.Identifier.ValueText;
                var    si   = context.SemanticModel.GetSymbolInfo(p);
                var    type = si.Symbol?.TryGetType();
                if (type != null)
                {
                    cparams[name] = new ContextualLinqParameter(name, type);
                }
                else
                {
                    cparams[name] = new ContextualLinqParameter(name);
                }
            }
            return(cparams);
        }
        private static void AnalyzeQueryExpression(SyntaxNodeAnalysisContext context, EFUsageContext efContext, QueryExpressionSyntax query)
        {
            //I can't believe how much easier this is compared to Extension Method syntax! Then again
            //query syntax does mean its own dedicated set of C# keywords, which would means its own
            //dedicated set of syntax node types


            //First item on checklist, find out our root queryable
            EFCodeFirstClassInfo cls;
            bool isConnectedToDbContext = GetRootEntityTypeFromLinqQuery(query.FromClause.Expression, context, efContext, out cls);

            if (cls != null)
            {
                bool treatAsWarning = !isConnectedToDbContext;

                var paramNodes  = ContextualLinqParameter.BuildContext(query, context, efContext);
                var descendants = query.Body.DescendantNodes();

                LinqExpressionValidator.ValidateLinqToEntitiesUsageInSyntaxNodes(descendants, cls, context, efContext, paramNodes, treatAsWarning);
            }
        }
 public static Dictionary<string, ContextualLinqParameter> BuildContext(IEnumerable<ParameterSyntax> parameters, SyntaxNodeAnalysisContext context, EFUsageContext efContext)
 {
     var cparams = new Dictionary<string, ContextualLinqParameter>();
     foreach (var p in parameters)
     {
         string name = p.Identifier.ValueText;
         var si = context.SemanticModel.GetSymbolInfo(p);
         var type = si.Symbol?.TryGetType();
         if (type != null)
             cparams[name] = new ContextualLinqParameter(name, type);
         else
             cparams[name] = new ContextualLinqParameter(name);
     }
     return cparams;
 }
        public static Dictionary<string, ContextualLinqParameter> BuildContext(QueryExpressionSyntax query, SyntaxNodeAnalysisContext context, EFUsageContext efContext)
        {
            var cparams = new Dictionary<string, ContextualLinqParameter>();

            //From x
            var fromExpr = query.FromClause.Identifier;
            //in <expr>
            var inExpr = query.FromClause.Expression;
            string name = fromExpr.ValueText;

            var memberExpr = inExpr as MemberAccessExpressionSyntax;
            if (memberExpr != null)
            {
                EFCodeFirstClassInfo cls;
                if (LinqExpressionValidator.MemberAccessIsAccessingDbContext(memberExpr, context, efContext, out cls))
                {
                    cparams[name] = new ContextualLinqParameter(name, cls);
                }
            }

            //Still not set, just set as a contextual parameter with no known type
            if (!cparams.ContainsKey(name))
                cparams[name] = new ContextualLinqParameter(name);

            return cparams;
        }