• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loresoft / FluentCommand / 23278216331

19 Mar 2026 03:19AM UTC coverage: 57.398% (+0.7%) from 56.658%
23278216331

push

github

pwelter34
Enable nullable and improve source generators

1403 of 3069 branches covered (45.72%)

Branch coverage included in aggregate %.

527 of 907 new or added lines in 58 files covered. (58.1%)

22 existing lines in 10 files now uncovered.

4288 of 6846 relevant lines covered (62.64%)

330.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.73
/src/FluentCommand/Query/SelectEntityBuilder.cs
1
using System.Linq.Expressions;
2

3
using FluentCommand.Extensions;
4
using FluentCommand.Query.Generators;
5
using FluentCommand.Reflection;
6

7
namespace FluentCommand.Query;
8

9
/// <summary>
10
/// Provides a builder for constructing SQL SELECT statements for a specific entity type with fluent, chainable methods.
11
/// </summary>
12
/// <typeparam name="TEntity">The type of the entity.</typeparam>
13
public class SelectEntityBuilder<TEntity>
14
    : SelectBuilder<SelectEntityBuilder<TEntity>>, IWhereEntityBuilder<TEntity, SelectEntityBuilder<TEntity>>
15
    where TEntity : class
16
{
17
    private static readonly TypeAccessor _typeAccessor = TypeAccessor.GetAccessor<TEntity>();
12✔
18

19
    /// <summary>
20
    /// Initializes a new instance of the <see cref="SelectEntityBuilder{TEntity}"/> class.
21
    /// </summary>
22
    /// <param name="queryGenerator">The <see cref="IQueryGenerator"/> used to generate SQL expressions.</param>
23
    /// <param name="parameters">The list of <see cref="QueryParameter"/> objects for the query.</param>
24
    /// <param name="logicalOperator">The logical operator (<see cref="LogicalOperators"/>) to combine WHERE expressions. Defaults to <see cref="LogicalOperators.And"/>.</param>
25
    public SelectEntityBuilder(IQueryGenerator queryGenerator, List<QueryParameter> parameters, LogicalOperators logicalOperator = LogicalOperators.And)
26
        : base(queryGenerator, parameters, logicalOperator)
51✔
27
    {
28
    }
51✔
29

30
    /// <summary>
31
    /// Adds a column expression for the specified entity property.
32
    /// </summary>
33
    /// <param name="property">An expression selecting the property to include in the SELECT clause.</param>
34
    /// <param name="tableAlias">The alias of the table (optional).</param>
35
    /// <param name="columnAlias">The alias for the column (optional).</param>
36
    /// <returns>
37
    /// The same builder instance for method chaining.
38
    /// </returns>
39
    public SelectEntityBuilder<TEntity> Column(
40
        Expression<Func<TEntity, object>> property,
41
        string? tableAlias = null,
42
        string? columnAlias = null)
43
    {
44
        var propertyAccessor = GetPropertyAccessor(property);
26✔
45

46
        // alias column as property name if they don't match
47
        if (propertyAccessor.Name == propertyAccessor.Column)
26✔
48
            return Column(propertyAccessor.Column, tableAlias, columnAlias);
25✔
49
        else
50
            return Column(propertyAccessor.Column, tableAlias, columnAlias ?? propertyAccessor.Name);
1✔
51
    }
52

53
    /// <summary>
54
    /// Adds a column expression for the specified property of a model type.
55
    /// </summary>
56
    /// <typeparam name="TModel">The type of the model.</typeparam>
57
    /// <param name="property">An expression selecting the property to include in the SELECT clause.</param>
58
    /// <param name="tableAlias">The alias of the table (optional).</param>
59
    /// <param name="columnAlias">The alias for the column (optional).</param>
60
    /// <returns>
61
    /// The same builder instance for method chaining.
62
    /// </returns>
63
    public SelectEntityBuilder<TEntity> Column<TModel>(
64
        Expression<Func<TModel, object>> property,
65
        string? tableAlias = null,
66
        string? columnAlias = null) where TModel : class
67
    {
68
        var typeAccessor = TypeAccessor.GetAccessor<TModel>();
6✔
69
        var propertyAccessor = GetPropertyAccessor(typeAccessor, property);
6✔
70

71
        // alias column as property name if they don't match
72
        if (propertyAccessor.Name == propertyAccessor.Column)
6!
73
            return Column(propertyAccessor.Column, tableAlias, columnAlias);
6✔
74
        else
75
            return Column(propertyAccessor.Column, tableAlias, columnAlias ?? propertyAccessor.Name);
×
76
    }
77

78
    /// <summary>
79
    /// Conditionally adds a column expression for the specified entity property.
80
    /// </summary>
81
    /// <typeparam name="TValue">The type of the property value.</typeparam>
82
    /// <param name="property">An expression selecting the property to include in the SELECT clause.</param>
83
    /// <param name="tableAlias">The alias of the table (optional).</param>
84
    /// <param name="columnAlias">The alias for the column (optional).</param>
85
    /// <param name="condition">A function that determines whether to add the column, based on the column name. If <c>null</c>, the column is always added.</param>
86
    /// <returns>
87
    /// The same builder instance for method chaining.
88
    /// </returns>
89
    public SelectEntityBuilder<TEntity> ColumnIf<TValue>(
90
        Expression<Func<TEntity, TValue>> property,
91
        string? tableAlias = null,
92
        string? columnAlias = null,
93
        Func<string, bool>? condition = null)
94
    {
NEW
95
        var propertyAccessor = GetPropertyAccessor(property);
×
96

97
        // alias column as property name if they don't match
98
        if (propertyAccessor.Name == propertyAccessor.Column)
×
99
            return ColumnIf(propertyAccessor.Column, tableAlias, columnAlias, condition);
×
100
        else
101
            return ColumnIf(propertyAccessor.Column, tableAlias, columnAlias ?? propertyAccessor.Name, condition);
×
102
    }
103

104
    /// <summary>
105
    /// Adds a column expression for each of the specified column names, using entity property mapping.
106
    /// </summary>
107
    /// <param name="columnNames">The collection of column names to include in the SELECT clause.</param>
108
    /// <param name="tableAlias">The alias of the table (optional).</param>
109
    /// <returns>
110
    /// The same builder instance for method chaining.
111
    /// </returns>
112
    /// <exception cref="ArgumentNullException">Thrown if <paramref name="columnNames"/> is <c>null</c>.</exception>
113
    public override SelectEntityBuilder<TEntity> Columns(
114
        IEnumerable<string> columnNames,
115
        string? tableAlias = null)
116
    {
117
        if (columnNames is null)
1!
118
            throw new ArgumentNullException(nameof(columnNames));
×
119

120
        foreach (var column in columnNames)
6✔
121
        {
122
            var propertyAccessor = _typeAccessor.FindColumn(column);
2✔
123
            if (propertyAccessor is null)
2✔
124
                continue;
125

126
            // alias column as property name if they don't match
127
            if (propertyAccessor.Name == propertyAccessor.Column)
2✔
128
                Column(propertyAccessor.Column, tableAlias);
1✔
129
            else
130
                Column(propertyAccessor.Column, tableAlias, propertyAccessor.Name);
1✔
131
        }
132

133
        return this;
1✔
134
    }
135

136
    /// <summary>
137
    /// Adds a column expression for each property in <typeparamref name="TEntity"/>.
138
    /// </summary>
139
    /// <param name="tableAlias">The alias of the table (optional).</param>
140
    /// <param name="filter">An optional filter to include properties.</param>
141
    /// <returns>
142
    /// The same builder instance for method chaining.
143
    /// </returns>
144
    public SelectEntityBuilder<TEntity> Columns(
145
        string? tableAlias = null,
146
        Func<IMemberAccessor, bool>? filter = null)
147
    {
148
        var properties = _typeAccessor.GetProperties();
3✔
149

150
        foreach (var property in properties)
144✔
151
        {
152
            if (property.IsNotMapped)
69✔
153
                continue;
154

155
            if (filter != null && !filter(property))
57✔
156
                continue;
157

158
            // alias column as property name if they don't match
159
            if (property.Name == property.Column)
56!
160
                Column(property.Column, tableAlias);
56✔
161
            else
162
                Column(property.Column, tableAlias, property.Name);
×
163
        }
164

165
        return this;
3✔
166
    }
167

168
    /// <summary>
169
    /// Adds a column expression for each property in <typeparamref name="TModel"/>.
170
    /// </summary>
171
    /// <typeparam name="TModel">The type of the model.</typeparam>
172
    /// <param name="tableAlias">The alias of the table (optional).</param>
173
    /// <param name="filter">An optional filter to include properties.</param>
174
    /// <returns>
175
    /// The same builder instance for method chaining.
176
    /// </returns>
177
    public SelectEntityBuilder<TEntity> Columns<TModel>(
178
        string? tableAlias = null,
179
        Func<IMemberAccessor, bool>? filter = null)
180
    {
NEW
181
        var typeAccessor = TypeAccessor.GetAccessor<TModel>();
×
182
        var properties = typeAccessor.GetProperties();
×
183

184
        foreach (var property in properties)
×
185
        {
186
            if (property.IsNotMapped)
×
187
                continue;
188

189
            if (filter != null && !filter(property))
×
190
                continue;
191

192
            // alias column as property name if they don't match
193
            if (property.Name == property.Column)
×
194
                Column(property.Column, tableAlias);
×
195
            else
196
                Column(property.Column, tableAlias, property.Name);
×
197
        }
198

199
        return this;
×
200
    }
201

202
    /// <summary>
203
    /// Adds a COUNT aggregate expression using the specified entity property.
204
    /// </summary>
205
    /// <typeparam name="TValue">The type of the property value.</typeparam>
206
    /// <param name="property">An expression selecting the property to count.</param>
207
    /// <param name="tableAlias">The alias of the table (optional).</param>
208
    /// <param name="columnAlias">The alias for the column (optional).</param>
209
    /// <returns>
210
    /// The same builder instance for method chaining.
211
    /// </returns>
212
    public SelectEntityBuilder<TEntity> Count<TValue>(
213
        Expression<Func<TEntity, TValue>> property,
214
        string? tableAlias = null,
215
        string? columnAlias = null)
216
    {
NEW
217
        var propertyAccessor = GetPropertyAccessor(property);
×
218

219
        return Count(propertyAccessor.Column, tableAlias, columnAlias);
×
220
    }
221

222
    /// <summary>
223
    /// Adds an aggregate expression using the specified function and entity property.
224
    /// </summary>
225
    /// <typeparam name="TValue">The type of the property value.</typeparam>
226
    /// <param name="property">An expression selecting the property to aggregate.</param>
227
    /// <param name="function">The aggregate function to use (e.g., <see cref="AggregateFunctions.Sum"/>).</param>
228
    /// <param name="tableAlias">The alias of the table (optional).</param>
229
    /// <param name="columnAlias">The alias for the column (optional).</param>
230
    /// <returns>
231
    /// The same builder instance for method chaining.
232
    /// </returns>
233
    public SelectEntityBuilder<TEntity> Aggregate<TValue>(
234
        Expression<Func<TEntity, TValue>> property,
235
        AggregateFunctions function,
236
        string? tableAlias = null,
237
        string? columnAlias = null)
238
    {
239
        var propertyAccessor = GetPropertyAccessor(property);
3✔
240

241
        return Aggregate(function, propertyAccessor.Column, tableAlias, columnAlias);
3✔
242
    }
243

244
    /// <summary>
245
    /// Sets the target table for the SELECT statement using the entity's mapping information by default.
246
    /// </summary>
247
    /// <param name="tableName">The name of the table (optional, defaults to entity mapping).</param>
248
    /// <param name="tableSchema">The schema of the table (optional, defaults to entity mapping).</param>
249
    /// <param name="tableAlias">The alias of the table (optional).</param>
250
    /// <returns>
251
    /// The same builder instance for method chaining.
252
    /// </returns>
253
    public override SelectEntityBuilder<TEntity> From(
254
        string? tableName = null,
255
        string? tableSchema = null,
256
        string? tableAlias = null)
257
    {
258
        return base.From(
48✔
259
            tableName ?? _typeAccessor.TableName,
48✔
260
            tableSchema ?? _typeAccessor.TableSchema,
48✔
261
            tableAlias);
48✔
262
    }
263

264
    /// <summary>
265
    /// Adds a JOIN clause to the SELECT statement using the specified builder action for the right entity.
266
    /// </summary>
267
    /// <typeparam name="TRight">The type of the right join entity.</typeparam>
268
    /// <param name="builder">An action that configures the join using a <see cref="JoinEntityBuilder{TEntity, TRight}"/>.</param>
269
    /// <returns>
270
    /// The same builder instance for method chaining.
271
    /// </returns>
272
    public SelectEntityBuilder<TEntity> Join<TRight>(Action<JoinEntityBuilder<TEntity, TRight>> builder)
273
        where TRight : class
274
    {
275
        var innerBuilder = new JoinEntityBuilder<TEntity, TRight>(QueryGenerator, Parameters);
7✔
276
        builder(innerBuilder);
7✔
277

278
        JoinExpressions.Add(innerBuilder.BuildExpression());
7✔
279

280
        return this;
7✔
281
    }
282

283
    /// <summary>
284
    /// Adds a JOIN clause to the SELECT statement using the specified builder action for the left and right entities.
285
    /// </summary>
286
    /// <typeparam name="TLeft">The type of the left join entity.</typeparam>
287
    /// <typeparam name="TRight">The type of the right join entity.</typeparam>
288
    /// <param name="builder">An action that configures the join using a <see cref="JoinEntityBuilder{TLeft, TRight}"/>.</param>
289
    /// <returns>
290
    /// The same builder instance for method chaining.
291
    /// </returns>
292
    public SelectEntityBuilder<TEntity> Join<TLeft, TRight>(Action<JoinEntityBuilder<TLeft, TRight>> builder)
293
        where TLeft : class
294
        where TRight : class
295
    {
296
        var innerBuilder = new JoinEntityBuilder<TLeft, TRight>(QueryGenerator, Parameters);
3✔
297
        builder(innerBuilder);
3✔
298

299
        JoinExpressions.Add(innerBuilder.BuildExpression());
3✔
300

301
        return this;
3✔
302
    }
303

304
    /// <inheritdoc />
305
    public SelectEntityBuilder<TEntity> Where<TValue>(
306
        Expression<Func<TEntity, TValue>> property,
307
        TValue? parameterValue,
308
        FilterOperators filterOperator = FilterOperators.Equal)
309
    {
310
        return Where<TValue>(property, parameterValue, null, filterOperator);
20✔
311
    }
312

313
    /// <inheritdoc />
314
    public SelectEntityBuilder<TEntity> Where<TValue>(
315
        Expression<Func<TEntity, TValue>> property,
316
        TValue? parameterValue,
317
        string? tableAlias,
318
        FilterOperators filterOperator = FilterOperators.Equal)
319
    {
320
        var propertyAccessor = GetPropertyAccessor(property);
24✔
321

322
        return Where(propertyAccessor.Column, parameterValue, tableAlias, filterOperator);
24✔
323
    }
324

325
    /// <summary>
326
    /// Adds a WHERE clause for the specified model property, value, filter operator, and table alias.
327
    /// </summary>
328
    /// <typeparam name="TModel">The type of the model.</typeparam>
329
    /// <typeparam name="TValue">The type of the value to compare.</typeparam>
330
    /// <param name="property">An expression selecting the property to filter on.</param>
331
    /// <param name="parameterValue">The value to compare the property against.</param>
332
    /// <param name="tableAlias">The alias of the table (optional).</param>
333
    /// <param name="filterOperator">The filter operator to use (default is <see cref="FilterOperators.Equal"/>).</param>
334
    /// <returns>
335
    /// The same builder instance for method chaining.
336
    /// </returns>
337
    public SelectEntityBuilder<TEntity> Where<TModel, TValue>(
338
        Expression<Func<TModel, TValue>> property,
339
        TValue? parameterValue,
340
        string? tableAlias,
341
        FilterOperators filterOperator = FilterOperators.Equal)
342
    {
343
        var typeAccessor = TypeAccessor.GetAccessor<TModel>();
1✔
344
        var propertyAccessor = GetPropertyAccessor(typeAccessor, property);
1✔
345

346
        return Where(propertyAccessor.Column, parameterValue, tableAlias, filterOperator);
1✔
347
    }
348

349
    /// <inheritdoc />
350
    public SelectEntityBuilder<TEntity> WhereIf<TValue>(
351
        Expression<Func<TEntity, TValue>> property,
352
        TValue? parameterValue,
353
        FilterOperators filterOperator = FilterOperators.Equal,
354
        Func<string, TValue?, bool>? condition = null)
355
    {
356
        return WhereIf(property, parameterValue, null, filterOperator, condition);
×
357
    }
358

359
    /// <inheritdoc />
360
    public SelectEntityBuilder<TEntity> WhereIf<TValue>(
361
        Expression<Func<TEntity, TValue>> property,
362
        TValue? parameterValue,
363
        string? tableAlias,
364
        FilterOperators filterOperator = FilterOperators.Equal,
365
        Func<string, TValue?, bool>? condition = null)
366
    {
NEW
367
        var propertyAccessor = GetPropertyAccessor(property);
×
368

369
        return WhereIf(propertyAccessor.Column, parameterValue, tableAlias, filterOperator, condition);
×
370
    }
371

372
    /// <inheritdoc />
373
    public SelectEntityBuilder<TEntity> WhereIn<TValue>(
374
        Expression<Func<TEntity, TValue>> property,
375
        IEnumerable<TValue> parameterValues,
376
        string? tableAlias = null)
377
    {
378
        var propertyAccessor = GetPropertyAccessor(property);
8✔
379

380
        return WhereIn(propertyAccessor.Column, parameterValues, tableAlias);
8✔
381
    }
382

383
    /// <inheritdoc />
384
    public SelectEntityBuilder<TEntity> WhereInIf<TValue>(
385
        Expression<Func<TEntity, TValue>> property,
386
        IEnumerable<TValue> parameterValues,
387
        Func<string, IEnumerable<TValue>, bool>? condition = null)
388
    {
389
        var propertyAccessor = GetPropertyAccessor(property);
1✔
390

391
        return WhereInIf(propertyAccessor.Column, parameterValues, condition);
1✔
392
    }
393

394
    /// <inheritdoc />
395
    public SelectEntityBuilder<TEntity> WhereInIf<TValue>(
396
        Expression<Func<TEntity, TValue>> property,
397
        IEnumerable<TValue> parameterValues,
398
        string? tableAlias,
399
        Func<string, IEnumerable<TValue>, bool>? condition = null)
400
    {
NEW
401
        var propertyAccessor = GetPropertyAccessor(property);
×
402

NEW
403
        return WhereInIf(propertyAccessor.Column, parameterValues, tableAlias, condition);
×
404
    }
405

406
    /// <inheritdoc />
407
    public SelectEntityBuilder<TEntity> WhereOr(Action<LogicalEntityBuilder<TEntity>> builder)
408
    {
409
        var innerBuilder = new LogicalEntityBuilder<TEntity>(QueryGenerator, Parameters, LogicalOperators.Or);
5✔
410

411
        builder(innerBuilder);
5✔
412

413
        var statement = innerBuilder.BuildStatement();
5✔
414

415
        if (statement != null)
5✔
416
            WhereExpressions.Add(new WhereExpression(statement.Statement, IsRaw: true));
5✔
417

418
        return this;
5✔
419
    }
420

421
    /// <inheritdoc />
422
    public SelectEntityBuilder<TEntity> WhereAnd(Action<LogicalEntityBuilder<TEntity>> builder)
423
    {
424
        var innerBuilder = new LogicalEntityBuilder<TEntity>(QueryGenerator, Parameters, LogicalOperators.And);
×
425

426
        builder(innerBuilder);
×
427

428
        var statement = innerBuilder.BuildStatement();
×
429

430
        if (statement != null && statement.Statement.HasValue())
×
431
            WhereExpressions.Add(new WhereExpression(statement.Statement, IsRaw: true));
×
432

433
        return this;
×
434
    }
435

436
    /// <summary>
437
    /// Adds an ORDER BY clause with the specified entity property and sort direction.
438
    /// </summary>
439
    /// <typeparam name="TValue">The type of the property value.</typeparam>
440
    /// <param name="property">An expression selecting the property to sort by.</param>
441
    /// <param name="sortDirection">The sort direction (default is <see cref="SortDirections.Ascending"/>).</param>
442
    /// <returns>
443
    /// The same builder instance for method chaining.
444
    /// </returns>
445
    public SelectEntityBuilder<TEntity> OrderBy<TValue>(
446
        Expression<Func<TEntity, TValue>> property,
447
        SortDirections sortDirection = SortDirections.Ascending)
448
    {
449
        var propertyAccessor = GetPropertyAccessor(property);
24✔
450

451
        return OrderBy(propertyAccessor.Column, null, sortDirection);
24✔
452
    }
453

454
    /// <summary>
455
    /// Adds an ORDER BY clause with the specified entity property, sort direction, and table alias.
456
    /// </summary>
457
    /// <typeparam name="TValue">The type of the property value.</typeparam>
458
    /// <param name="property">An expression selecting the property to sort by.</param>
459
    /// <param name="tableAlias">The alias of the table (optional).</param>
460
    /// <param name="sortDirection">The sort direction (default is <see cref="SortDirections.Ascending"/>).</param>
461
    /// <returns>
462
    /// The same builder instance for method chaining.
463
    /// </returns>
464
    public SelectEntityBuilder<TEntity> OrderBy<TValue>(
465
        Expression<Func<TEntity, TValue>> property,
466
        string? tableAlias,
467
        SortDirections sortDirection = SortDirections.Ascending)
468
    {
469
        var propertyAccessor = GetPropertyAccessor(property);
4✔
470

471
        return OrderBy(propertyAccessor.Column, tableAlias, sortDirection);
4✔
472
    }
473

474
    /// <summary>
475
    /// Conditionally adds an ORDER BY clause with the specified entity property and sort direction.
476
    /// </summary>
477
    /// <typeparam name="TValue">The type of the property value.</typeparam>
478
    /// <param name="property">An expression selecting the property to sort by.</param>
479
    /// <param name="sortDirection">The sort direction (default is <see cref="SortDirections.Ascending"/>).</param>
480
    /// <param name="condition">A function that determines whether to add the ORDER BY clause, based on the property name. If <c>null</c>, the clause is always added.</param>
481
    /// <returns>
482
    /// The same builder instance for method chaining.
483
    /// </returns>
484
    public SelectEntityBuilder<TEntity> OrderByIf<TValue>(
485
        Expression<Func<TEntity, TValue>> property,
486
        SortDirections sortDirection = SortDirections.Ascending,
487
        Func<string, bool>? condition = null)
488
    {
NEW
489
        var propertyAccessor = GetPropertyAccessor(property);
×
490

491
        return OrderByIf(propertyAccessor.Column, null, sortDirection, condition);
×
492
    }
493

494
    /// <summary>
495
    /// Conditionally adds an ORDER BY clause with the specified entity property, sort direction, and table alias.
496
    /// </summary>
497
    /// <typeparam name="TValue">The type of the property value.</typeparam>
498
    /// <param name="property">An expression selecting the property to sort by.</param>
499
    /// <param name="tableAlias">The alias of the table (optional).</param>
500
    /// <param name="sortDirection">The sort direction (default is <see cref="SortDirections.Ascending"/>).</param>
501
    /// <param name="condition">A function that determines whether to add the ORDER BY clause, based on the property name. If <c>null</c>, the clause is always added.</param>
502
    /// <returns>
503
    /// The same builder instance for method chaining.
504
    /// </returns>
505
    public SelectEntityBuilder<TEntity> OrderByIf<TValue>(
506
        Expression<Func<TEntity, TValue>> property,
507
        string? tableAlias,
508
        SortDirections sortDirection = SortDirections.Ascending,
509
        Func<string, bool>? condition = null)
510
    {
NEW
511
        var propertyAccessor = GetPropertyAccessor(property);
×
512

513
        return OrderByIf(propertyAccessor.Column, tableAlias, sortDirection, condition);
×
514
    }
515

516
    /// <summary>
517
    /// Adds a GROUP BY clause with the specified entity property and table alias.
518
    /// </summary>
519
    /// <typeparam name="TValue">The type of the property value.</typeparam>
520
    /// <param name="property">An expression selecting the property to group by.</param>
521
    /// <param name="tableAlias">The alias of the table (optional).</param>
522
    /// <returns>
523
    /// The same builder instance for method chaining.
524
    /// </returns>
525
    public SelectEntityBuilder<TEntity> GroupBy<TValue>(
526
        Expression<Func<TEntity, TValue>> property,
527
        string? tableAlias = null)
528
    {
529
        var propertyAccessor = GetPropertyAccessor(property);
3✔
530

531
        return GroupBy(propertyAccessor.Column, tableAlias);
3✔
532
    }
533

534
    /// <summary>
535
    /// Builds the SQL SELECT statement using the current configuration.
536
    /// </summary>
537
    /// <returns>
538
    /// A <see cref="QueryStatement"/> containing the SQL SELECT statement and its parameters.
539
    /// </returns>
540
    public override QueryStatement? BuildStatement()
541
    {
542
        // add table and schema from attribute if not set
543
        if (FromExpressions.Count == 0)
51✔
544
            From(_typeAccessor.TableName, _typeAccessor.TableSchema);
43✔
545

546
        return base.BuildStatement();
51✔
547
    }
548

549
    private static IMemberAccessor GetPropertyAccessor<TModel, TValue>(
550
        TypeAccessor typeAccessor,
551
        Expression<Func<TModel, TValue>> property)
552
    {
553
        if (property is null)
100!
NEW
554
            throw new ArgumentNullException(nameof(property));
×
555

556
        var propertyAccessor = typeAccessor.FindProperty(property);
100✔
557
        if (propertyAccessor is null)
100!
NEW
558
            throw new ArgumentException("The specified property does not exist on the entity.", nameof(property));
×
559

560
        return propertyAccessor;
100✔
561
    }
562

563
    private static IMemberAccessor GetPropertyAccessor<TValue>(Expression<Func<TEntity, TValue>> property)
564
        => GetPropertyAccessor(_typeAccessor, property);
93✔
565
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc