Fauna v10 .NET/C# Driver 1.0.0
 
Loading...
Searching...
No Matches
QuerySourceDsl.cs
Go to the documentation of this file.
1using System.Diagnostics;
2using System.Linq.Expressions;
3using System.Runtime.CompilerServices;
5using Fauna.Mapping;
7using Fauna.Util;
9
10namespace Fauna.Linq;
11
12public partial class QuerySource<T>
13{
14 private Query Query { get => Pipeline.Query; }
15 private MappingContext MappingCtx { get => Ctx.MappingCtx; }
16 private LookupTable Lookup { get => Ctx.LookupTable; }
17
18 // Composition methods
19
22 {
23 RequireQueryMode();
24 return Chain<T>(q: QH.MethodCall(Query, "distinct"));
25 }
26
29 {
30 RequireQueryMode();
31 return Chain<T>(q: QH.MethodCall(Query, "order"));
32 }
33
35 public IQuerySource<T> OrderBy<K>(Expression<Func<T, K>> keySelector)
36 {
37 RequireQueryMode();
38 return Chain<T>(q: QH.MethodCall(Query, "order", SubQuery(keySelector)));
39 }
40
42 public IQuerySource<T> OrderByDescending<K>(Expression<Func<T, K>> keySelector)
43 {
44 RequireQueryMode();
45 return Chain<T>(q: QH.MethodCall(Query, "order", QH.FnCall("desc", SubQuery(keySelector))));
46 }
47
50 {
51 RequireQueryMode();
52 return Chain<T>(q: QH.MethodCall(Query, "order", QH.Expr("desc(x => x)")));
53 }
54
57 Chain<T>(q: QH.MethodCall(Query, "reverse"));
58
60 public IQuerySource<R> Select<R>(Expression<Func<T, R>> selector)
61 {
62 var pl = SelectCall(Query, selector);
63 return new QuerySource<R>(Ctx, pl);
64 }
65
67 public IQuerySource<T> Skip(int count) =>
68 Chain<T>(q: QH.MethodCall(Query, "drop", QH.Const(count)));
69
71 public IQuerySource<T> Take(int count) =>
72 Chain<T>(q: QH.MethodCall(Query, "take", QH.Const(count)));
73
75 public IQuerySource<T> Where(Expression<Func<T, bool>> predicate) =>
76 Chain<T>(q: WhereCall(Query, predicate));
77
78 // Terminal result methods
79
81 public bool All(Expression<Func<T, bool>> predicate) => Execute<bool>(AllImpl(predicate));
83 public Task<bool> AllAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = default) =>
84 ExecuteAsync<bool>(AllImpl(predicate), cancel);
85 private Pipeline AllImpl(Expression<Func<T, bool>> predicate)
86 {
87 RequireQueryMode("All");
88 return CopyPipeline(
89 mode: PipelineMode.Scalar,
90 q: QH.MethodCall(Query, "every", SubQuery(predicate)),
91 ety: typeof(bool));
92 }
93
95 public bool Any() => Execute<bool>(AnyImpl(null));
97 public Task<bool> AnyAsync(CancellationToken cancel = default) =>
98 ExecuteAsync<bool>(AnyImpl(null), cancel);
100 public bool Any(Expression<Func<T, bool>> predicate) => Execute<bool>(AnyImpl(predicate));
102 public Task<bool> AnyAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = default) =>
103 ExecuteAsync<bool>(AnyImpl(predicate), cancel);
104 private Pipeline AnyImpl(Expression<Func<T, bool>>? predicate) =>
105 CopyPipeline(
106 mode: PipelineMode.Scalar,
107 q: QH.MethodCall(MaybeWhereCall(Query, predicate), "nonEmpty"),
108 ety: typeof(bool));
109
111 public int Count() => Execute<int>(CountImpl(null));
113 public Task<int> CountAsync(CancellationToken cancel = default) =>
114 ExecuteAsync<int>(CountImpl(null), cancel);
116 public int Count(Expression<Func<T, bool>> predicate) => Execute<int>(CountImpl(predicate));
118 public Task<int> CountAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = default) =>
119 ExecuteAsync<int>(CountImpl(predicate), cancel);
120 private Pipeline CountImpl(Expression<Func<T, bool>>? predicate) =>
121 CopyPipeline(
122 mode: PipelineMode.Scalar,
123 q: QH.MethodCall(MaybeWhereCall(Query, predicate), "count"),
124 ety: typeof(int));
125
127 public T First() => Execute<T>(FirstImpl(null));
129 public Task<T> FirstAsync(CancellationToken cancel = default) =>
130 ExecuteAsync<T>(FirstImpl(null), cancel);
132 public T First(Expression<Func<T, bool>> predicate) => Execute<T>(FirstImpl(predicate));
134 public Task<T> FirstAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = default) =>
135 ExecuteAsync<T>(FirstImpl(predicate), cancel);
136 private Pipeline FirstImpl(Expression<Func<T, bool>>? predicate) =>
137 CopyPipeline(
138 mode: PipelineMode.Scalar,
139 q: QH.MethodCall(AbortIfEmpty(MaybeWhereCall(Query, predicate)), "first"));
140
142 public T? FirstOrDefault() => Execute<T?>(FirstOrDefaultImpl(null));
144 public Task<T?> FirstOrDefaultAsync(CancellationToken cancel = default) =>
145 ExecuteAsync<T?>(FirstOrDefaultImpl(null), cancel);
147 public T? FirstOrDefault(Expression<Func<T, bool>> predicate) => Execute<T?>(FirstOrDefaultImpl(predicate));
149 public Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = default) =>
150 ExecuteAsync<T?>(FirstOrDefaultImpl(predicate), cancel);
151 private Pipeline FirstOrDefaultImpl(Expression<Func<T, bool>>? predicate) =>
152 CopyPipeline(
153 mode: PipelineMode.Scalar,
154 q: QH.MethodCall(MaybeWhereCall(Query, predicate), "first"),
155 ety: typeof(T),
156 enull: true);
157
159 public T Last() => Execute<T>(LastImpl(null));
161 public Task<T> LastAsync(CancellationToken cancel = default) =>
162 ExecuteAsync<T>(LastImpl(null), cancel);
164 public T Last(Expression<Func<T, bool>> predicate) => Execute<T>(LastImpl(predicate));
166 public Task<T> LastAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = default) =>
167 ExecuteAsync<T>(LastImpl(predicate), cancel);
168 private Pipeline LastImpl(Expression<Func<T, bool>>? predicate) =>
169 CopyPipeline(
170 mode: PipelineMode.Scalar,
171 q: QH.MethodCall(AbortIfEmpty(MaybeWhereCall(Query, predicate)), "last"));
172
174 public T? LastOrDefault() => Execute<T?>(LastOrDefaultImpl(null));
176 public Task<T?> LastOrDefaultAsync(CancellationToken cancel = default) =>
177 ExecuteAsync<T?>(LastOrDefaultImpl(null), cancel);
179 public T? LastOrDefault(Expression<Func<T, bool>> predicate) => Execute<T?>(LastOrDefaultImpl(predicate));
181 public Task<T?> LastOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = default) =>
182 ExecuteAsync<T?>(LastOrDefaultImpl(predicate), cancel);
183 private Pipeline LastOrDefaultImpl(Expression<Func<T, bool>>? predicate) =>
184 CopyPipeline(
185 mode: PipelineMode.Scalar,
186 q: QH.MethodCall(MaybeWhereCall(Query, predicate), "last"),
187 ety: typeof(T),
188 enull: true);
189
191 public long LongCount() => Execute<long>(LongCountImpl(null));
193 public Task<long> LongCountAsync(CancellationToken cancel = default) =>
194 ExecuteAsync<long>(LongCountImpl(null), cancel);
196 public long LongCount(Expression<Func<T, bool>> predicate) => Execute<long>(LongCountImpl(predicate));
198 public Task<long> LongCountAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = default) =>
199 ExecuteAsync<long>(LongCountImpl(predicate), cancel);
200 private Pipeline LongCountImpl(Expression<Func<T, bool>>? predicate) =>
201 CopyPipeline(
202 mode: PipelineMode.Scalar,
203 q: QH.MethodCall(MaybeWhereCall(Query, predicate), "count"),
204 ety: typeof(long));
205
206 private static readonly Query _maxReducer = QH.Expr("(a, b) => if (a >= b) a else b");
207
209 public T Max() => Execute<T>(MaxImpl<T>(null));
211 public Task<T> MaxAsync(CancellationToken cancel = default) =>
212 ExecuteAsync<T>(MaxImpl<T>(null), cancel);
214 public R Max<R>(Expression<Func<T, R>> selector) => Execute<R>(MaxImpl(selector));
216 public Task<R> MaxAsync<R>(Expression<Func<T, R>> selector, CancellationToken cancel = default) =>
217 ExecuteAsync<R>(MaxImpl(selector), cancel);
218 private Pipeline MaxImpl<R>(Expression<Func<T, R>>? selector, [CallerMemberName] string callerName = "")
219 {
220 RequireQueryMode(callerName);
221 return CopyPipeline(
222 mode: PipelineMode.Scalar,
223 q: QH.MethodCall(MaybeMap(AbortIfEmpty(Query), selector), "reduce", _maxReducer),
224 ety: typeof(R));
225 }
226
227 private static readonly Query _minReducer = QH.Expr("(a, b) => if (a <= b) a else b");
228
230 public T Min() => Execute<T>(MinImpl<T>(null));
232 public Task<T> MinAsync(CancellationToken cancel = default) => ExecuteAsync<T>(MinImpl<T>(null), cancel);
234 public R Min<R>(Expression<Func<T, R>> selector) => Execute<R>(MinImpl(selector));
236 public Task<R> MinAsync<R>(Expression<Func<T, R>> selector, CancellationToken cancel = default) =>
237 ExecuteAsync<R>(MinImpl(selector), cancel);
238 private Pipeline MinImpl<R>(Expression<Func<T, R>>? selector, [CallerMemberName] string callerName = "")
239 {
240 RequireQueryMode(callerName);
241 return CopyPipeline(
242 mode: PipelineMode.Scalar,
243 q: QH.MethodCall(MaybeMap(AbortIfEmpty(Query), selector), "reduce", _minReducer),
244 ety: typeof(R));
245 }
246
248 public double Average(Expression<Func<T, double>> selector) => Execute<double>(AverageImpl(selector));
250 public Task<double> AverageAsync(Expression<Func<T, double>> selector, CancellationToken cancel = default) =>
251 ExecuteAsync<double>(AverageImpl(selector), cancel);
252
253 private Pipeline AverageImpl<R>(Expression<Func<T, R>> selector)
254 {
255 RequireQueryMode("Average");
256
257 return CopyPipeline(
258 mode: PipelineMode.Scalar,
259 q: QH.FnCall("Math.mean", QH.MethodCall(QH.MethodCall(AbortIfEmpty(Query), "map", SubQuery(selector)), "toArray")),
260 ety: typeof(R));
261 }
262
264 public T Single() => Execute<T>(SingleImpl(null));
266 public Task<T> SingleAsync(CancellationToken cancel = default) => ExecuteAsync<T>(SingleImpl(null), cancel);
268 public T Single(Expression<Func<T, bool>> predicate) => Execute<T>(SingleImpl(predicate));
270 public Task<T> SingleAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = default) =>
271 ExecuteAsync<T>(SingleImpl(predicate), cancel);
272 private Pipeline SingleImpl(Expression<Func<T, bool>>? predicate) =>
273 CopyPipeline(
274 mode: PipelineMode.Scalar,
275 q: QH.MethodCall(AbortIfEmpty(Singularize(MaybeWhereCall(Query, predicate))), "first"));
276
278 public T SingleOrDefault() => Execute<T>(SingleOrDefaultImpl(null));
280 public Task<T> SingleOrDefaultAsync(CancellationToken cancel = default) => ExecuteAsync<T>(SingleOrDefaultImpl(null), cancel);
282 public T SingleOrDefault(Expression<Func<T, bool>> predicate) => Execute<T>(SingleOrDefaultImpl(predicate));
284 public Task<T> SingleOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancel = default) =>
285 ExecuteAsync<T>(SingleOrDefaultImpl(predicate), cancel);
286 private Pipeline SingleOrDefaultImpl(Expression<Func<T, bool>>? predicate) =>
287 CopyPipeline(
288 mode: PipelineMode.Scalar,
289 q: QH.MethodCall(Singularize(MaybeWhereCall(Query, predicate)), "first"),
290 ety: typeof(T),
291 enull: true);
292
293 private static readonly Query _sumReducer = QH.Expr("(a, b) => a + b");
294
296 public int Sum(Expression<Func<T, int>> selector) => Execute<int>(SumImpl<int>(selector));
298 public Task<int> SumAsync(Expression<Func<T, int>> selector, CancellationToken cancel = default) =>
299 ExecuteAsync<int>(SumImpl<int>(selector), cancel);
301 public long Sum(Expression<Func<T, long>> selector) => Execute<long>(SumImpl<long>(selector));
303 public Task<long> SumAsync(Expression<Func<T, long>> selector, CancellationToken cancel = default) =>
304 ExecuteAsync<long>(SumImpl<long>(selector), cancel);
306 public double Sum(Expression<Func<T, double>> selector) => Execute<double>(SumImpl<double>(selector));
308 public Task<double> SumAsync(Expression<Func<T, double>> selector, CancellationToken cancel = default) =>
309 ExecuteAsync<double>(SumImpl<double>(selector), cancel);
310 private Pipeline SumImpl<R>(Expression<Func<T, R>> selector)
311 {
312 RequireQueryMode("Sum");
313 var seed = (typeof(R) == typeof(int) || typeof(R) == typeof(long)) ?
314 QH.Expr("0") :
315 QH.Expr("0.0");
316 var mapped = QH.MethodCall(Query, "map", SubQuery(selector));
317 return CopyPipeline(
318 mode: PipelineMode.Scalar,
319 q: QH.MethodCall(mapped, "fold", seed, _sumReducer),
320 ety: typeof(R));
321 }
322
323 // helpers
324
325 private void RequireQueryMode([CallerMemberName] string callerName = "")
326 {
327 if (Pipeline.Mode != PipelineMode.Query)
328 {
329 throw IQuerySource.Fail(
330 callerName,
331 $"Query is not pure: Earlier `Select` could not be translated to pure FQL.");
332 }
333 }
334
335 private R Execute<R>(Pipeline pl)
336 {
337 try
338 {
339 var res = ExecuteAsync<R>(pl);
340 res.Wait();
341 return res.Result;
342 }
343 catch (AggregateException ex)
344 {
345 throw TranslateException(ex.InnerExceptions.First());
346 }
347 }
348
349 private async Task<R> ExecuteAsync<R>(Pipeline pl, CancellationToken cancel = default)
350 {
351 try
352 {
353 return await pl.GetExec(Ctx).Result<R>(queryOptions: null, cancel: cancel);
354 }
355 catch (AggregateException ex)
356 {
357 throw TranslateException(ex.InnerExceptions.First());
358 }
359 }
360
361 private QuerySource<R> Chain<R>(
362 PipelineMode? mode = null,
363 Query? q = null,
364 ISerializer? ser = null,
365 Type? ety = null,
366 bool enull = false,
367 LambdaExpression? proj = null) =>
368 new QuerySource<R>(Ctx, CopyPipeline(mode, q, ser, ety, enull, proj));
369
370 private Pipeline CopyPipeline(
371 PipelineMode? mode = null,
372 Query? q = null,
373 ISerializer? ser = null,
374 Type? ety = null,
375 bool enull = false,
376 LambdaExpression? proj = null)
377 {
378 if (ser is not null) Debug.Assert(ety is not null);
379
380 var mode0 = mode ?? Pipeline.Mode;
381 var q0 = q ?? Pipeline.Query;
382
383 // if ety is not null, reset ser and proj if not provided.
384 var (ety0, enull0, ser0, proj0) = ety is not null ?
385 (ety, enull, ser, proj) :
386 (Pipeline.ElemType,
387 Pipeline.ElemNullable,
388 Pipeline.ElemSerializer,
389 proj ?? Pipeline.ProjectExpr);
390
391 return new Pipeline(mode0, q0, ety0, enull0, ser0, proj0);
392 }
393
394 // There is a bug in abort data deserialization if the abort
395 // value is a string. Work around it by using an array.
396 // FIXME(matt) remove workaround and use a string
397 private Query AbortIfEmpty(Query setq) =>
398 QH.Expr(@"({ let s = (").Concat(setq).Concat(@")
399 if (s.isEmpty()) abort(['empty'])
400 s
401 })");
402
403 private Query Singularize(Query setq) =>
404 QH.Expr(@"({
405 let s = (").Concat(setq).Concat(@")
406 let s = if (s isa Set) s.toArray() else s
407 if (s isa Array) {
408 if (s.length > 1) abort(['not single'])
409 s.take(1)
410 } else {
411 [s]
412 }
413 })");
414
415 private Exception TranslateException(Exception ex) =>
416 ex switch
417 {
418 AbortException aex =>
419 aex.GetData<List<string>>()?.First() switch
420 {
421 "empty" => new InvalidOperationException("Empty set"),
422 "not single" => new InvalidOperationException("Set contains more than one element"),
423 _ => aex,
424 },
425 _ => ex
426 };
427
428 private Query MaybeWhereCall(Query callee, Expression? predicate, [CallerMemberName] string callerName = "") =>
429 predicate is null ? callee : WhereCall(callee, predicate, callerName);
430
431 private Query MaybeMap(Query setq, Expression? selector) =>
432 selector is null ? setq : QH.MethodCall(setq, "map", SubQuery(selector));
433
434 private Query SubQuery(Expression expr) =>
435 new SubQuerySwitch(Ctx.LookupTable).Apply(expr);
436
437 private Query WhereCall(Query callee, Expression predicate, [CallerMemberName] string callerName = "")
438 {
439 RequireQueryMode(callerName);
440 return QH.MethodCall(callee, "where", SubQuery(predicate));
441 }
442
443 private Pipeline SelectCall(Query callee, Expression proj, [CallerMemberName] string callerName = "")
444 {
445 var lambda = Expressions.UnwrapLambda(proj);
446 Debug.Assert(lambda is not null, $"lambda is {proj.NodeType}");
447 Debug.Assert(lambda.Parameters.Count() == 1);
448
449 // there is already a projection wired up, so tack on to its mapping lambda
450 if (Pipeline.Mode == PipelineMode.Project)
451 {
452 Debug.Assert(Pipeline.ProjectExpr is not null);
453 var prev = Pipeline.ProjectExpr;
454 var pbody = Expression.Invoke(lambda, new Expression[] { prev.Body });
455 var plambda = Expression.Lambda(pbody, prev.Parameters);
456
457 return CopyPipeline(proj: plambda);
458 }
459
460 Debug.Assert(Pipeline.Mode == PipelineMode.Query);
461
462 var lparam = lambda.Parameters.First()!;
463 var analysis = new ProjectionAnalysisVisitor(MappingCtx, lparam);
464 analysis.Visit(lambda.Body);
465
466 // select is a simple field access which we can translate directly to FQL.
467 // TODO(matt) translate more cases to pure FQL
468 if (lambda.Body is MemberExpression mexpr && mexpr.Expression == lparam)
469 {
470 Debug.Assert(!analysis.Escapes);
471 var info = MappingCtx.GetInfo(lparam.Type);
472 var access = analysis.Accesses.First();
473 var field = Lookup.FieldLookup(access, lparam);
474 Debug.Assert(field is not null);
475
476 return CopyPipeline(
477 q: QH.MethodCall(callee, "map", QH.Expr($".{field.Name}")),
478 ser: field.Serializer,
479 ety: field.Type);
480 }
481
482 if (analysis.Escapes)
483 {
484 return CopyPipeline(mode: PipelineMode.Project, proj: lambda);
485 }
486 else
487 {
488 var accesses = analysis.Accesses.OrderBy(f => f.Name).ToArray();
489 var fields = accesses.Select(a => Lookup.FieldLookup(a, lparam)!);
490
491 // projection query fragment
492 var accs = fields.Select(f => QH.Expr($"x.{f.Name}"));
493 var pquery = QH.Expr("x => ").Concat(QH.Array(accs));
494
495 // projected field deserializer
496 var deser = new ProjectionDeserializer(fields.Select(f => f.Serializer));
497 var ety = typeof(object?[]);
498
499 // build mapping lambda expression
500 var pparam = Expression.Parameter(typeof(object?[]), "x");
501 var rewriter = new ProjectionRewriteVisitor(lparam, accesses, pparam);
502 var pbody = rewriter.Visit(lambda.Body);
503 var plambda = Expression.Lambda(pbody, pparam);
504
505 return CopyPipeline(
506 q: QH.MethodCall(callee, "map", pquery),
507 mode: PipelineMode.Project,
508 ser: deser,
509 ety: ety,
510 proj: plambda);
511 }
512 }
513}
Fauna.Linq.IntermediateQueryHelpers QH
Represents an exception that occurs when the FQL abort function is called. This exception captures th...
object? GetData()
Retrieves the deserialized data associated with the abort operation as an object.
An abstract class representing a QuerySource for LINQ-style queries.
Task< int > CountAsync(CancellationToken cancel=default)
Applies a count of the elements and executes the query asynchronously. This is evaluated server-side....
Task< T?> FirstOrDefaultAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
Applies the predicate, executes the query asynchronously, and obtains the first element in the result...
double Average(Expression< Func< T, double > > selector)
Calculates the mean average of values returned by a provided selector. This is evaluated server-side....
Task< bool > AllAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
Applies each predicate and executes the query asynchronously. This is evaluated server-side....
Task< long > SumAsync(Expression< Func< T, long > > selector, CancellationToken cancel=default)
Asynchronously calculates the sum of values returned by a provided selector. This is evaluated server...
Task< T > SingleOrDefaultAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
Applies the predicate and executes the query asynchronously. If the result is a single element,...
Task< T > FirstAsync(CancellationToken cancel=default)
Executes the query asynchronously and obtains the first element in the result. This is evaluated serv...
Task< T > FirstAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
Applies the predicate, executes the query asynchronously, and obtains the first element in the result...
bool Any()
Determines if the result is not empty. This is evaluated server-side.True if the result contains any ...
double Sum(Expression< Func< T, double > > selector)
Calculates the sum of values returned by a provided selector. This is evaluated server-side....
T SingleOrDefault(Expression< Func< T, bool > > predicate)
Applies the predicate and executes the query. If the result is a single element, returns it....
Task< T > MinAsync(CancellationToken cancel=default)
Executes a query asynchronously and returns the minimum value in the result set. This is evaluated se...
Task< double > AverageAsync(Expression< Func< T, double > > selector, CancellationToken cancel=default)
Asynchronously calculates the mean average of values returned by a provided selector....
bool Any(Expression< Func< T, bool > > predicate)
Applies each predicate and executes the query. This is evaluated server-side.True if any predicate ev...
Task< T?> FirstOrDefaultAsync(CancellationToken cancel=default)
Executes the query asynchronously and obtains the first element in the result or the default value,...
Task< int > SumAsync(Expression< Func< T, int > > selector, CancellationToken cancel=default)
Asynchronously calculates the sum of values returned by a provided selector. This is evaluated server...
T Single()
Executes the query. If the result is a single element, returns it. Otherwise, throws an exception....
Task< int > CountAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
Applies the predicate, applies a count, and executes the query asynchronously. This is evaluated serv...
IQuerySource< T > OrderByDescending< K >(Expression< Func< T, K > > keySelector)
Orders by descending according to the selector. This is evaluated server-side.This IQuerySource<T> in...
R Min< R >(Expression< Func< T, R > > selector)
Applies the selector, executes the query, and returns the minimum value in the result set....
Task< T > LastAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
Applies the predicate, executes the query asynchronously, and obtains the last element in the result....
T? FirstOrDefault(Expression< Func< T, bool > > predicate)
Applies the predicate, executes the query, and obtains the first element in the result or the default...
T SingleOrDefault()
Executes the query. If the result is a single element, returns it. Otherwise, returns the default....
T First(Expression< Func< T, bool > > predicate)
Applies the predicate, executes the query, and obtains the first element in the result....
Task< T > LastAsync(CancellationToken cancel=default)
Executes the query asynchronously and obtains the last element in the result. This is evaluated serve...
IQuerySource< T > Reverse()
Reverses the order of the results. This is evaluated server-side.This IQuerySource<T> instance.
T Max()
Executes a query and returns the maximum value in the result set. This is evaluated server-side....
Task< R > MinAsync< R >(Expression< Func< T, R > > selector, CancellationToken cancel=default)
Applies the selector, executes the query asynchronously, and returns the minimum value in the result ...
IQuerySource< T > Skip(int count)
Skips the first N elements of the results. This is evaluated server-side.This IQuerySource<T> instanc...
Task< T > SingleOrDefaultAsync(CancellationToken cancel=default)
Executes the query asynchronously. If the result is a single element, returns it. Otherwise,...
IQuerySource< T > Where(Expression< Func< T, bool > > predicate)
Applies the predicate to the query. This is evaluated server-side.This IQuerySource<T> instance.
IQuerySource< T > OrderDescending()
Orders by descending. This is evaluated server-side.This IQuerySource<T> instance.
int Count()
Applies a count of the elements and executes the query. This is evaluated server-side....
T? LastOrDefault()
Executes the query and obtains the last element in the result or the default value,...
bool All(Expression< Func< T, bool > > predicate)
Applies each predicate and executes the query. This is evaluated server-side.True if every predicate ...
Task< R > MaxAsync< R >(Expression< Func< T, R > > selector, CancellationToken cancel=default)
Applies a selector, executes a query asynchronously, and returns the maximum value in the result set....
IQuerySource< T > Order()
Applies default ordering to the query. This is evaluated server-side.This IQuerySource<T> instance.
long LongCount(Expression< Func< T, bool > > predicate)
Applies the predicate, applies a count, and executes the query. This is evaluated server-side....
Task< T?> LastOrDefaultAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
Applies the predicate, executes the query asynchronously and obtains the last element in the result o...
int Sum(Expression< Func< T, int > > selector)
Calculates the sum of values returned by a provided selector. This is evaluated server-side....
T Last()
Executes the query and obtains the last element in the result. This is evaluated server-side....
IQuerySource< T > Take(int count)
Takes the first N elements of the results. This is evaluated server-side.This IQuerySource<T> instanc...
Task< T > SingleAsync(CancellationToken cancel=default)
Executes the query asynchronously. If the result is a single element, returns it. Otherwise,...
T Single(Expression< Func< T, bool > > predicate)
Applies the predicate and executes the query. If the result is a single element, returns it....
IQuerySource< T > Distinct()
Obtains a distinct set of results. This is evaluated server-side.This IQuerySource<T> instance.
Task< long > LongCountAsync(CancellationToken cancel=default)
Applies a count of the elements and executes the query asynchronously. This is evaluated server-side....
Task< double > SumAsync(Expression< Func< T, double > > selector, CancellationToken cancel=default)
Asynchronously calculates the sum of values returned by a provided selector. This is evaluated server...
Task< T?> LastOrDefaultAsync(CancellationToken cancel=default)
Executes the query asynchronously and obtains the last element in the result or the default value,...
long LongCount()
Applies a count of the elements and executes the query. This is evaluated server-side....
T First()
Executes the query and obtains the first element in the result. This is evaluated server-side....
Task< T > SingleAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
Applies the predicate and executes the query asynchronously. If the result is a single element,...
T? LastOrDefault(Expression< Func< T, bool > > predicate)
Applies the predicate, executes the query and obtains the last element in the result or the default v...
Task< bool > AnyAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
Applies each predicate and executes the query asynchronously. This is evaluated server-side....
T Last(Expression< Func< T, bool > > predicate)
Applies the predicate, executes the query, and obtains the last element in the result....
IQuerySource< T > OrderBy< K >(Expression< Func< T, K > > keySelector)
Orders according to the selector. This is evaluated server-side.This IQuerySource<T> instance.
Task< T > MaxAsync(CancellationToken cancel=default)
Executes a query asynchronously and returns the maximum value in the result set. This is evaluated se...
T Min()
Executes a query and returns the minimum value in the result set. This is evaluated server-side....
Task< long > LongCountAsync(Expression< Func< T, bool > > predicate, CancellationToken cancel=default)
Applies the predicate, applies a count, and executes the query asynchronously. This is evaluated serv...
long Sum(Expression< Func< T, long > > selector)
Calculates the sum of values returned by a provided selector. This is evaluated server-side....
IQuerySource< R > Select< R >(Expression< Func< T, R > > selector)
Applies a projection to the query. This is evaluated server-side.This IQuerySource<T> instance.
Task< bool > AnyAsync(CancellationToken cancel=default)
Determines if the result is not empty asynchronously. This is evaluated server-side....
R Max< R >(Expression< Func< T, R > > selector)
Applies a selector, executes a query, and returns the maximum value in the result set....
int Count(Expression< Func< T, bool > > predicate)
Applies the predicate, applies a count, and executes the query. This is evaluated server-side....
T? FirstOrDefault()
Executes the query and obtains the first element in the result or the default value,...
A class representing the mapping context to be used during serialization and deserialization.
MappingInfo GetInfo(Type ty, string? colName=null)
Gets the MappingInfo for a given Type.
Represents the abstract base class for constructing FQL queries.
Definition Query.cs:11
An interface for common static IQuerySource methods that are non-generic.
A generic interface that defines serialize and deserialize behavior for a specific type,...
PipelineMode
The mode of the query pipeline.
Definition Pipeline.cs:10
@ Project
When elements have local projection.
@ Scalar
When there is a final, non-enum result, no more transformations are allowed.