If there are no common values between the sets of SuFundCode and NaFundCode then sticking with the query comprehension syntax, this should work:
var fundCodeGroups = (from sar in aidItems
group sar by (sar.SuFundCode.Substring(0, 2) == "SA" ?
sar.SuFundCode : sar.NaFundCode)
into sa
select sa).ToList();
Or using the more compact (and in this case more readable, IMO) fluent/lambda syntax:
var fundCodeGroups = aidItems
.GroupBy(sar => sar.SuFundCode.Substring(0, 2) == "SA" ?
sar.SuFundCode : sar.NaFundCode)
.ToList();
Otherwise, any of these should work, although only the last returns the same kind of grouping as your original:
var fundCodeGroups1 = (from sar in aidItems
group sar by new { IsSA = sar.SuFundCode.Substring(0, 2) == "SA",
Code = (sar.SuFundCode.Substring(0, 2) == "SA" ? sar.SuFundCode : sar.NaFundCode) }
into sa
select sa).ToList();
var fundCodeGroups2 = aidItems
.GroupBy(sar => new { IsSA = sar.SuFundCode.Substring(0, 2) == "SA",
Code = (sar.SuFundCode.Substring(0, 2) == "SA" ? sar.SuFundCode : sar.NaFundCode) })
.ToList();
var fundCodeGroups3 = aidItems
.GroupBy(sar => sar.SuFundCode.Substring(0, 2) == "SA")
.SelectMany(g => g.Key ? g.GroupBy(i => i.SuFundCode) : g.GroupBy(i => i.NaFundCode))
.ToList();
I'm not sure that any of these of offer better clarity or performance than your original solution, though.