Таким образом, в C#, когда вы используете LINQ-to- SQL запросов , вы используете методы расширения для IQueryable<T>
. Если мы посмотрим на сигнатуру скажем, метод GroupBy
, вы увидите, что сигнатура функции на самом деле
IQueryable<TSource>.GroupBy<TSource,TKey>(Expression<Func<TSource,TKey>> keySelector)
Что происходит? Expression<>
- это специальный тип - когда компилятор C# обнаруживает тип Expression<>
, компилятор создает AST и передает объект AST (типа Expression<Func<>>
) вместо обычного делегата. Предполагается, что базовые функции будут проверять AST и создавать любое необходимое выражение запроса, например, SQL для запроса к базе данных.
Вы можете попробовать сами:
Expression<Func<int>> getRandom = () => 4; //random, chosen by fair dice roll
Вы можете проверьте свойства getRandom
, чтобы увидеть AST. Поскольку magi c происходит в компиляторе C#, когда вы делаете это в F #, это не обрезает его.
To go более подробно, компилятор F # может распознавать Expression<>
, но делает это, применяя неявную цитату F # - так вы получаете вызов метода с обёрткой цитаты F #, который преобразуется в дерево выражений C#. (Извините, если он был запущен.)
F # имеет собственный интерпретатор запросов строитель для SQL. Это позволяет вам писать выражения для вычислений, такие как seq
, которые переводят в SQL запросы. Это работает так, как вы ожидаете.
query {
for record in db do
select record
}