Я думаю, что нашел фактический ответ на эту проблему. Я порылся в источнике SubSonic и обнаружил, что существует два типа проекции объектов, которые используются при отображении хранилища данных на объекты: один для анонимных типов и группировок и один для всего остального:
Вот фрагмент: строка 269 - 298 из SubSonic.Linq.Structure.DbQueryProvider
IEnumerable<T> result;
Type type = typeof (T);
//this is so hacky - the issue is that the Projector below uses Expression.Convert, which is a bottleneck
//it's about 10x slower than our ToEnumerable. Our ToEnumerable, however, stumbles on Anon types and groupings
//since it doesn't know how to instantiate them (I tried - not smart enough). So we do some trickery here.
if (type.Name.Contains("AnonymousType") || type.Name.StartsWith("Grouping`") || type.FullName.StartsWith("System.")) {
var reader = _provider.ExecuteReader(cmd);
result = Project(reader, query.Projector);
} else
{
using (var reader = _provider.ExecuteReader(cmd))
{
//use our reader stuff
//thanks to Pascal LaCroix for the help here...
var resultType = typeof (T);
if (resultType.IsValueType)
{
result = reader.ToEnumerableValueType<T>();
}
else
{
result = reader.ToEnumerable<T>();
}
}
}
return result;
Оказывается, что SubSonic ToEnumerable пытается сопоставить имена столбцов в устройстве чтения данных со свойствами объекта, на который вы пытаетесь проецировать. Запрос SQL из моего Linq выглядит так:
SELECT [t0].[Id], [t0].[ProductId], [t0].[ReleaseDate], [t0].[ReleasedBy], [t0].[ReleaseNumber], [t0].[RevisionNumber], [t0].[c0]
FROM (
SELECT [t1].[Id], [t1].[ProductId], [t1].[ReleaseDate], [t1].[ReleasedBy], [t1].[ReleaseNumber], [t1].[RevisionNumber], (
SELECT COUNT(*)
FROM [dbo].[Install] AS t2
WHERE ([t2].[ReleaseId] = [t1].[Id])
) AS c0
FROM [dbo].[Release] AS t1
) AS t0
WHERE ([t0].[ProductId] = 2)
Обратите внимание, что [t0]. [C0] не совпадает с именем моего свойства NumberOfInstalls. Таким образом, значение c0 никогда не проецируется на мой объект.
ИСПРАВЛЕНИЕ:
Вы можете просто взять оператор if и использовать в 10 раз более медленную проекцию, и все будет работать.