private static void ValidateNavigationPropertyAccess(InvocationExpressionSyntax node, SyntaxNodeAnalysisContext context, EFUsageContext efContext, bool treatAsWarning, string memberName, EFCodeFirstClassInfo cls)
{
if (node.ArgumentList.Arguments.Count == 1 &&
node.ArgumentList.Arguments[0].Expression.Kind() != SyntaxKind.SimpleLambdaExpression)
{
if (node.ArgumentList.Arguments[0].Expression.Kind() == SyntaxKind.IdentifierName)
{
//Follow the identifier back to its assignment
var si = context.SemanticModel.GetSymbolInfo(node.ArgumentList.Arguments[0].Expression);
if (si.Symbol?.Kind == SymbolKind.Local)
{
var type = si.Symbol?.TryGetType() as INamedTypeSymbol;
//The variable inside our LINQ sub-operator is a Func<T, bool> where T
//is a known entity type
if (type != null &&
type.MetadataName == $"{EFSpecialIdentifiers.Func}`2" &&
efContext.GetClassInfo(type.TypeArguments[0]) != null &&
type.TypeArguments[1].MetadataName == EFSpecialIdentifiers.Boolean)
{
//TODO: Code fix candidate
//
//In such a case, inject an .AsQueryable() before the LINQ operator call
//and add using System.Linq if required and convert the variable from Func<T, bool> to Expression<Func<T, bool>>
var diagnostic = Diagnostic.Create(treatAsWarning ? DiagnosticCodes.EFLINQ009 : DiagnosticCodes.EFLINQ008, node.ArgumentList.Arguments[0].Expression.GetLocation(), memberName, cls.Name);
context.ReportDiagnostic(diagnostic);
}
}
}
}
}