如何声明带有复杂查询的System.Linq.IQueryable类型变量?
The error you're seeing happens because IQueryable<T> is a generic interface that only accepts one type argument—you can't pass multiple types directly like you tried. To solve this, you have two solid options depending on your needs:
Option 1: Create a Custom Class (Recommended for Reusability)
If this result type will be used in multiple parts of your codebase, defining a concrete class makes your code more readable and maintainable.
First, define a class that matches the structure of your query's output:
public class SchemeExpenditureResult { public string ProjectName { get; set; } public int ADPNo { get; set; } public decimal Allocation { get; set; } public IEnumerable<IGrouping<string, Expenditure>> Expenditures { get; set; } }
Then declare your result variable using this class as the type argument:
System.Linq.IQueryable<SchemeExpenditureResult> result = null;
Finally, update your LINQ query to instantiate this class instead of using an anonymous type:
result = from sch in schemeDashboard join exp in Expenditure on sch.schemeId equals exp.SchemeCode into SchExpGroup where sch.SectorDepartmentId == selectedDepartmentId && sch.YearCode == StateManager.CurrentYear orderby sch.ADPId select new SchemeExpenditureResult { ProjectName = sch.schemeName, ADPNo = sch.ADPId, Allocation = sch.CurrentAllocation, Expenditures = from expend in SchExpGroup where expend.YearCode == StateManager.CurrentYear && expend.DepartmentId == selectedDepartmentId && InvStatus.Contains(expend.Status) orderby expend.ADPId group expend by expend.InvoiceId };
Option 2: Use a Value Tuple (Quick for One-Off Use)
If this is a one-off scenario and you're using C# 7.0 or later, you can use a value tuple to avoid creating a separate class.
Declare your result variable with a named tuple type:
System.Linq.IQueryable<(string ProjectName, int ADPNo, decimal Allocation, IEnumerable<IGrouping<string, Expenditure>> Expenditures)> result = null;
Then adjust your LINQ query to return the tuple:
result = from sch in schemeDashboard join exp in Expenditure on sch.schemeId equals exp.SchemeCode into SchExpGroup where sch.SectorDepartmentId == selectedDepartmentId && sch.YearCode == StateManager.CurrentYear orderby sch.ADPId select ( ProjectName: sch.schemeName, ADPNo: sch.ADPId, Allocation: sch.CurrentAllocation, Expenditures: from expend in SchExpGroup where expend.YearCode == StateManager.CurrentYear && expend.DepartmentId == selectedDepartmentId && InvStatus.Contains(expend.Status) orderby expend.ADPId group expend by expend.InvoiceId );
Which Option to Choose?
- Custom Class: Best if you need to reuse this type elsewhere, or if you want to add methods/validation to the result.
- Value Tuple: Faster to implement for single-use cases, keeps your code concise without extra class definitions.
内容的提问来源于stack exchange,提问作者AKA

