Ниже приведен пример нескольких столбцов, используемых для группировки в c # и преобразования в f # (чрезмерно параноидальное управление заставило меня переименовать все, но я считаю, что я был последовательным):
(была создана база данныхпо SqlMetal, GetSummedValuesResult является типом записи F #)
c #
public static class Reports
{
public static IReadOnlyList<GetSummedValuesResult> GetSummedValues(TheDatabase db, DateTime startDate, DateTime? endDate)
{
var query =
from sv in db.SomeValues
where (sv.ADate >= startDate && sv.ADate <= (endDate ?? startDate))
group sv by new { sv.ADate, sv.Owner.Name } into grouping
select new GetSummedValuesResult(
grouping.Key.ADate,
grouping.Key.Name,
grouping.Sum(g => g.Value)
);
return query.ToList();
}
}
f #
type Reports() =
static member GetSummedValues (db:TheDatabase) startDate (endDate:Nullable<DateTime>) =
let endDate = if endDate.HasValue then endDate.Value else startDate
let q = query {
for sv in db.SomeValues do
where (sv.ADate >= startDate && sv.ADate <= endDate)
let key = AnonymousObject<_,_>(sv.ADate, sv.Owner.Name)
groupValBy sv key into grouping
select {
ADate = grouping.Key.Item1;
AName = grouping.Key.Item2;
SummedValues = grouping.Sum (fun (g:TheDatabaseSchema.SomeValues) -> g.Value)
}
}
List(q) :> IReadOnlyList<GetSummedValuesResult>
Таким образом, нужно использовать Microsoft.FSharp.Linq.RuntimeHelpers.AnonymousObject
Обратите внимание, что вы не должны использовать модуль Seq для функций агрегирования !!
SummedValues = grouping |> Seq.sumBy (fun g -> g.SomeValues)
Хотя это БУДЕТ РАБОТАТЬ, оно выполняет агрегацию на стороне клиента, а не формулирует соответствующий SQL.