Repository: maxtoroq/DbExtensions Branch: v7 Commit: 07fbefe6fe6c Files: 503 Total size: 1.3 MB Directory structure: gitextract_v6wr0hj4/ ├── .gitattributes ├── .github/ │ └── FUNDING.yml ├── .gitignore ├── .gitmodules ├── CHANGES.md ├── DbExtensions.sln ├── LICENSE.txt ├── NOTICE.xml ├── README.md ├── appveyor.yml ├── build/ │ ├── .gitignore │ ├── DbExtensions.shfbproj │ ├── build-docs.ps1 │ ├── ensure-nuget.ps1 │ └── release.ps1 ├── docs/ │ ├── README.md │ ├── SqlBuilder.md │ ├── SqlSet.md │ └── api/ │ ├── DbExtensions/ │ │ ├── AssociationAttribute/ │ │ │ ├── Name.md │ │ │ ├── OtherKey.md │ │ │ ├── README.md │ │ │ ├── ThisKey.md │ │ │ └── _ctor.md │ │ ├── AutoSync/ │ │ │ └── README.md │ │ ├── ChangeConflictException/ │ │ │ ├── README.md │ │ │ └── _ctor.md │ │ ├── ColumnAttribute/ │ │ │ ├── AutoSync.md │ │ │ ├── ConvertTo.md │ │ │ ├── IsDbGenerated.md │ │ │ ├── IsPrimaryKey.md │ │ │ ├── IsVersion.md │ │ │ ├── Name.md │ │ │ ├── README.md │ │ │ └── _ctor.md │ │ ├── ComplexPropertyAttribute/ │ │ │ ├── Name.md │ │ │ ├── README.md │ │ │ ├── Separator.md │ │ │ └── _ctor.md │ │ ├── Database/ │ │ │ ├── Add.md │ │ │ ├── AddAsync.md │ │ │ ├── AsyncMap.md │ │ │ ├── AsyncMap_1.md │ │ │ ├── AsyncMap__1.md │ │ │ ├── AsyncMap__1_1.md │ │ │ ├── Configuration.md │ │ │ ├── Connection.md │ │ │ ├── CreateCommand.md │ │ │ ├── Dispose.md │ │ │ ├── Dispose_1.md │ │ │ ├── EnsureConnectionOpen.md │ │ │ ├── EnsureConnectionOpenAsync.md │ │ │ ├── EnsureInTransaction.md │ │ │ ├── EnsureInTransactionAsync.md │ │ │ ├── EnsureInTransactionAsync_1.md │ │ │ ├── EnsureInTransaction_1.md │ │ │ ├── Execute.md │ │ │ ├── ExecuteAsync.md │ │ │ ├── FindAsync__1.md │ │ │ ├── Find__1.md │ │ │ ├── From.md │ │ │ ├── FromQuery.md │ │ │ ├── FromQuery_1.md │ │ │ ├── FromQuery__1.md │ │ │ ├── FromQuery__1_1.md │ │ │ ├── From_1.md │ │ │ ├── From__1.md │ │ │ ├── LastInsertId.md │ │ │ ├── LastInsertIdAsync.md │ │ │ ├── Map.md │ │ │ ├── Map_1.md │ │ │ ├── Map__1.md │ │ │ ├── Map__1_1.md │ │ │ ├── QuoteIdentifier.md │ │ │ ├── README.md │ │ │ ├── Remove.md │ │ │ ├── RemoveAsync.md │ │ │ ├── Table.md │ │ │ ├── Table__1.md │ │ │ ├── Transaction.md │ │ │ ├── Update.md │ │ │ ├── UpdateAsync.md │ │ │ ├── UpdateAsync_1.md │ │ │ ├── Update_1.md │ │ │ ├── _ctor.md │ │ │ └── _ctor_1.md │ │ ├── DatabaseConfiguration/ │ │ │ ├── CommandTimeout.md │ │ │ ├── DefaultComplexPropertySeparator.md │ │ │ ├── EnableBatchCommands.md │ │ │ ├── LastInsertIdCommand.md │ │ │ ├── Log.md │ │ │ ├── ParameterNameBuilder.md │ │ │ ├── ParameterPlaceholderBuilder.md │ │ │ ├── QuotePrefix.md │ │ │ ├── QuoteSuffix.md │ │ │ ├── README.md │ │ │ └── UseVersionMember.md │ │ ├── Extensions/ │ │ │ ├── GetBoolean.md │ │ │ ├── GetByte.md │ │ │ ├── GetChar.md │ │ │ ├── GetDateTime.md │ │ │ ├── GetDecimal.md │ │ │ ├── GetDouble.md │ │ │ ├── GetFloat.md │ │ │ ├── GetInt16.md │ │ │ ├── GetInt32.md │ │ │ ├── GetInt64.md │ │ │ ├── GetNullableBoolean.md │ │ │ ├── GetNullableBoolean_1.md │ │ │ ├── GetNullableByte.md │ │ │ ├── GetNullableByte_1.md │ │ │ ├── GetNullableChar.md │ │ │ ├── GetNullableChar_1.md │ │ │ ├── GetNullableDateTime.md │ │ │ ├── GetNullableDateTime_1.md │ │ │ ├── GetNullableDecimal.md │ │ │ ├── GetNullableDecimal_1.md │ │ │ ├── GetNullableDouble.md │ │ │ ├── GetNullableDouble_1.md │ │ │ ├── GetNullableFloat.md │ │ │ ├── GetNullableFloat_1.md │ │ │ ├── GetNullableGuid.md │ │ │ ├── GetNullableGuid_1.md │ │ │ ├── GetNullableInt16.md │ │ │ ├── GetNullableInt16_1.md │ │ │ ├── GetNullableInt32.md │ │ │ ├── GetNullableInt32_1.md │ │ │ ├── GetNullableInt64.md │ │ │ ├── GetNullableInt64_1.md │ │ │ ├── GetString.md │ │ │ ├── GetStringOrNull.md │ │ │ ├── GetStringOrNull_1.md │ │ │ ├── GetValue.md │ │ │ ├── GetValueOrNull.md │ │ │ ├── GetValueOrNull_1.md │ │ │ └── README.md │ │ ├── README.md │ │ ├── SQL/ │ │ │ ├── DELETE_FROM.md │ │ │ ├── DELETE_FROM_1.md │ │ │ ├── INSERT_INTO.md │ │ │ ├── INSERT_INTO_1.md │ │ │ ├── README.md │ │ │ ├── SELECT.md │ │ │ ├── SELECT_1.md │ │ │ ├── UPDATE.md │ │ │ ├── UPDATE_1.md │ │ │ ├── WITH.md │ │ │ ├── WITH_1.md │ │ │ ├── WITH_2.md │ │ │ └── WITH_3.md │ │ ├── SqlBuilder/ │ │ │ ├── Append.md │ │ │ ├── AppendClause.md │ │ │ ├── AppendClause__1.md │ │ │ ├── AppendElse.md │ │ │ ├── AppendElseIf.md │ │ │ ├── AppendIf.md │ │ │ ├── AppendLine.md │ │ │ ├── AppendSql.md │ │ │ ├── Append_1.md │ │ │ ├── Buffer.md │ │ │ ├── CROSS_JOIN.md │ │ │ ├── CROSS_JOIN_1.md │ │ │ ├── CROSS_JOIN_2.md │ │ │ ├── Clone.md │ │ │ ├── CurrentClause.md │ │ │ ├── DELETE_FROM.md │ │ │ ├── DELETE_FROM_1.md │ │ │ ├── FROM.md │ │ │ ├── FROM_1.md │ │ │ ├── FROM_2.md │ │ │ ├── FROM_3.md │ │ │ ├── FROM_4.md │ │ │ ├── GROUP_BY.md │ │ │ ├── GROUP_BY_1.md │ │ │ ├── GROUP_BY_2.md │ │ │ ├── HAVING.md │ │ │ ├── HAVING_1.md │ │ │ ├── HAVING_2.md │ │ │ ├── INNER_JOIN.md │ │ │ ├── INNER_JOIN_1.md │ │ │ ├── INNER_JOIN_2.md │ │ │ ├── INSERT_INTO.md │ │ │ ├── INSERT_INTO_1.md │ │ │ ├── InsertText.md │ │ │ ├── IsEmpty.md │ │ │ ├── JOIN.md │ │ │ ├── JOIN_1.md │ │ │ ├── JOIN_2.md │ │ │ ├── JoinSql.md │ │ │ ├── JoinSql_1.md │ │ │ ├── LEFT_JOIN.md │ │ │ ├── LEFT_JOIN_1.md │ │ │ ├── LEFT_JOIN_2.md │ │ │ ├── LIMIT.md │ │ │ ├── LIMIT_1.md │ │ │ ├── LIMIT_2.md │ │ │ ├── LIMIT_3.md │ │ │ ├── NextClause.md │ │ │ ├── OFFSET.md │ │ │ ├── OFFSET_1.md │ │ │ ├── OFFSET_2.md │ │ │ ├── OFFSET_3.md │ │ │ ├── ORDER_BY.md │ │ │ ├── ORDER_BY_1.md │ │ │ ├── ORDER_BY_2.md │ │ │ ├── ParameterValues.md │ │ │ ├── README.md │ │ │ ├── RIGHT_JOIN.md │ │ │ ├── RIGHT_JOIN_1.md │ │ │ ├── RIGHT_JOIN_2.md │ │ │ ├── SELECT.md │ │ │ ├── SELECT_1.md │ │ │ ├── SELECT_2.md │ │ │ ├── SET.md │ │ │ ├── SET_1.md │ │ │ ├── SetCurrentClause.md │ │ │ ├── SetCurrentClause__1.md │ │ │ ├── SetNextClause.md │ │ │ ├── SetNextClause__1.md │ │ │ ├── ToString.md │ │ │ ├── UNION.md │ │ │ ├── UPDATE.md │ │ │ ├── UPDATE_1.md │ │ │ ├── VALUES.md │ │ │ ├── VALUES_1.md │ │ │ ├── WHERE.md │ │ │ ├── WHERE_1.md │ │ │ ├── WHERE_2.md │ │ │ ├── WITH.md │ │ │ ├── WITH_1.md │ │ │ ├── WITH_2.md │ │ │ ├── WITH_3.md │ │ │ ├── _.md │ │ │ ├── _Else.md │ │ │ ├── _ElseIf.md │ │ │ ├── _If.md │ │ │ └── __1.md │ │ ├── SqlClause/ │ │ │ ├── Instance__1.md │ │ │ ├── Name.md │ │ │ ├── README.md │ │ │ ├── Separator.md │ │ │ └── _ctor.md │ │ ├── SqlSet/ │ │ │ ├── All.md │ │ │ ├── AllAsync.md │ │ │ ├── AllAsync_1.md │ │ │ ├── All_1.md │ │ │ ├── Any.md │ │ │ ├── AnyAsync.md │ │ │ ├── AnyAsync_1.md │ │ │ ├── AnyAsync_2.md │ │ │ ├── Any_1.md │ │ │ ├── Any_2.md │ │ │ ├── AsAsyncEnumerable.md │ │ │ ├── AsEnumerable.md │ │ │ ├── Cast.md │ │ │ ├── Cast__1.md │ │ │ ├── Contains.md │ │ │ ├── ContainsAsync.md │ │ │ ├── ContainsKey.md │ │ │ ├── ContainsKeyAsync.md │ │ │ ├── Count.md │ │ │ ├── CountAsync.md │ │ │ ├── CountAsync_1.md │ │ │ ├── CountAsync_2.md │ │ │ ├── Count_1.md │ │ │ ├── Count_2.md │ │ │ ├── Database.md │ │ │ ├── Find.md │ │ │ ├── FindAsync.md │ │ │ ├── First.md │ │ │ ├── FirstAsync.md │ │ │ ├── FirstAsync_1.md │ │ │ ├── FirstAsync_2.md │ │ │ ├── FirstOrDefault.md │ │ │ ├── FirstOrDefaultAsync.md │ │ │ ├── FirstOrDefaultAsync_1.md │ │ │ ├── FirstOrDefaultAsync_2.md │ │ │ ├── FirstOrDefault_1.md │ │ │ ├── FirstOrDefault_2.md │ │ │ ├── First_1.md │ │ │ ├── First_2.md │ │ │ ├── GetAsyncEnumerator.md │ │ │ ├── GetDefiningQuery.md │ │ │ ├── GetEnumerator.md │ │ │ ├── Include.md │ │ │ ├── IncludeMany.md │ │ │ ├── LongCount.md │ │ │ ├── LongCountAsync.md │ │ │ ├── LongCountAsync_1.md │ │ │ ├── LongCountAsync_2.md │ │ │ ├── LongCount_1.md │ │ │ ├── LongCount_2.md │ │ │ ├── OrderBy.md │ │ │ ├── OrderBy_1.md │ │ │ ├── README.md │ │ │ ├── ResultType.md │ │ │ ├── Select.md │ │ │ ├── Select_1.md │ │ │ ├── Select_2.md │ │ │ ├── Select_3.md │ │ │ ├── Select__1.md │ │ │ ├── Select__1_1.md │ │ │ ├── Select__1_2.md │ │ │ ├── Select__1_3.md │ │ │ ├── Single.md │ │ │ ├── SingleAsync.md │ │ │ ├── SingleAsync_1.md │ │ │ ├── SingleAsync_2.md │ │ │ ├── SingleOrDefault.md │ │ │ ├── SingleOrDefaultAsync.md │ │ │ ├── SingleOrDefaultAsync_1.md │ │ │ ├── SingleOrDefaultAsync_2.md │ │ │ ├── SingleOrDefault_1.md │ │ │ ├── SingleOrDefault_2.md │ │ │ ├── Single_1.md │ │ │ ├── Single_2.md │ │ │ ├── Skip.md │ │ │ ├── Take.md │ │ │ ├── ToArray.md │ │ │ ├── ToArrayAsync.md │ │ │ ├── ToList.md │ │ │ ├── ToListAsync.md │ │ │ ├── ToString.md │ │ │ ├── Where.md │ │ │ └── Where_1.md │ │ ├── SqlSet_1/ │ │ │ ├── AsAsyncEnumerable.md │ │ │ ├── AsEnumerable.md │ │ │ ├── Contains.md │ │ │ ├── ContainsAsync.md │ │ │ ├── Find.md │ │ │ ├── FindAsync.md │ │ │ ├── First.md │ │ │ ├── FirstAsync.md │ │ │ ├── FirstAsync_1.md │ │ │ ├── FirstAsync_2.md │ │ │ ├── FirstOrDefault.md │ │ │ ├── FirstOrDefaultAsync.md │ │ │ ├── FirstOrDefaultAsync_1.md │ │ │ ├── FirstOrDefaultAsync_2.md │ │ │ ├── FirstOrDefault_1.md │ │ │ ├── FirstOrDefault_2.md │ │ │ ├── First_1.md │ │ │ ├── First_2.md │ │ │ ├── GetAsyncEnumerator.md │ │ │ ├── GetEnumerator.md │ │ │ ├── Include.md │ │ │ ├── IncludeMany.md │ │ │ ├── IncludeMany__1.md │ │ │ ├── Include_1.md │ │ │ ├── OrderBy.md │ │ │ ├── OrderBy_1.md │ │ │ ├── README.md │ │ │ ├── Single.md │ │ │ ├── SingleAsync.md │ │ │ ├── SingleAsync_1.md │ │ │ ├── SingleAsync_2.md │ │ │ ├── SingleOrDefault.md │ │ │ ├── SingleOrDefaultAsync.md │ │ │ ├── SingleOrDefaultAsync_1.md │ │ │ ├── SingleOrDefaultAsync_2.md │ │ │ ├── SingleOrDefault_1.md │ │ │ ├── SingleOrDefault_2.md │ │ │ ├── Single_1.md │ │ │ ├── Single_2.md │ │ │ ├── Skip.md │ │ │ ├── Take.md │ │ │ ├── ToArray.md │ │ │ ├── ToArrayAsync.md │ │ │ ├── ToList.md │ │ │ ├── ToListAsync.md │ │ │ ├── Where.md │ │ │ └── Where_1.md │ │ ├── SqlTable/ │ │ │ ├── Add.md │ │ │ ├── AddAsync.md │ │ │ ├── AddRange.md │ │ │ ├── AddRangeAsync.md │ │ │ ├── AddRangeAsync_1.md │ │ │ ├── AddRange_1.md │ │ │ ├── Cast__1.md │ │ │ ├── Name.md │ │ │ ├── README.md │ │ │ ├── Refresh.md │ │ │ ├── RefreshAsync.md │ │ │ ├── Remove.md │ │ │ ├── RemoveAsync.md │ │ │ ├── RemoveKey.md │ │ │ ├── RemoveKeyAsync.md │ │ │ ├── RemoveRange.md │ │ │ ├── RemoveRangeAsync.md │ │ │ ├── RemoveRangeAsync_1.md │ │ │ ├── RemoveRange_1.md │ │ │ ├── Update.md │ │ │ ├── UpdateAsync.md │ │ │ ├── UpdateAsync_1.md │ │ │ ├── UpdateRange.md │ │ │ ├── UpdateRangeAsync.md │ │ │ ├── UpdateRangeAsync_1.md │ │ │ ├── UpdateRange_1.md │ │ │ └── Update_1.md │ │ ├── SqlTable_1/ │ │ │ ├── Add.md │ │ │ ├── AddAsync.md │ │ │ ├── AddRange.md │ │ │ ├── AddRangeAsync.md │ │ │ ├── AddRangeAsync_1.md │ │ │ ├── AddRange_1.md │ │ │ ├── Name.md │ │ │ ├── README.md │ │ │ ├── Refresh.md │ │ │ ├── RefreshAsync.md │ │ │ ├── Remove.md │ │ │ ├── RemoveAsync.md │ │ │ ├── RemoveKey.md │ │ │ ├── RemoveKeyAsync.md │ │ │ ├── RemoveRange.md │ │ │ ├── RemoveRangeAsync.md │ │ │ ├── RemoveRangeAsync_1.md │ │ │ ├── RemoveRange_1.md │ │ │ ├── Update.md │ │ │ ├── UpdateAsync.md │ │ │ ├── UpdateAsync_1.md │ │ │ ├── UpdateRange.md │ │ │ ├── UpdateRangeAsync.md │ │ │ ├── UpdateRangeAsync_1.md │ │ │ ├── UpdateRange_1.md │ │ │ └── Update_1.md │ │ └── TableAttribute/ │ │ ├── Name.md │ │ ├── README.md │ │ └── _ctor.md │ └── README.md ├── samples/ │ ├── App/ │ │ ├── App.config │ │ ├── Northwind/ │ │ │ ├── Northwind.mdf │ │ │ ├── Northwind.sl3 │ │ │ └── Northwind_log.ldf │ │ ├── Program.cs │ │ ├── Samples.App.csproj │ │ └── Utilities/ │ │ ├── ObjectDumper-LICENSE.txt │ │ └── ObjectDumper.cs │ └── CSharp/ │ ├── Database.Annotated.cs │ ├── Database.Poco.cs │ ├── Northwind/ │ │ ├── Category.cs │ │ ├── Customer.cs │ │ ├── CustomerCustomerDemo.cs │ │ ├── CustomerDemographic.cs │ │ ├── Employee.cs │ │ ├── EmployeeTerritory.cs │ │ ├── NorthwindDatabase.cs │ │ ├── Order.cs │ │ ├── OrderDetail.cs │ │ ├── Product.cs │ │ ├── Region.cs │ │ ├── Shipper.cs │ │ ├── Supplier.cs │ │ └── Territory.cs │ ├── Samples.CSharp.csproj │ ├── SqlBuilder.cs │ └── SqlSet.cs ├── src/ │ ├── DbExtensions/ │ │ ├── .editorconfig │ │ ├── Attributes.cs │ │ ├── Database.cs │ │ ├── DbExtensions.csproj │ │ ├── DynamicMapper.cs │ │ ├── Extensions.cs │ │ ├── Mapper.cs │ │ ├── Metadata/ │ │ │ ├── Accessors.cs │ │ │ ├── AttributedMetaModel.cs │ │ │ ├── Error.cs │ │ │ ├── MappingSource.cs │ │ │ ├── MappingSystem.cs │ │ │ ├── MetaModel.cs │ │ │ └── TypeSystem.cs │ │ ├── PocoMapper.cs │ │ ├── Properties/ │ │ │ └── AssemblyInfo.cs │ │ ├── SqlBuilder.cs │ │ ├── SqlSet.Async.cs │ │ ├── SqlSet.cs │ │ ├── SqlTable.Async.cs │ │ ├── SqlTable.SqlSet.cs │ │ └── SqlTable.cs │ ├── DbExtensions-QE/ │ │ ├── DbExtensions-QE.csproj │ │ └── README.md │ ├── DbExtensions.SqlBuilder/ │ │ ├── DbExtensions.SqlBuilder.csproj │ │ └── README.md │ └── DbExtensions.SqlSet/ │ ├── DbExtensions.SqlSet.csproj │ └── README.md └── tests/ └── DbExtensions.Tests/ ├── DbExtensions.Tests.csproj ├── Mapping/ │ ├── DynamicMappingBehavior.cs │ ├── EnumMappingBehavior.cs │ ├── PersistentComplexPropertiesBehavior.cs │ ├── PocoMappingBehavior.cs │ ├── PocoMappingConstructorBehavior.cs │ └── PocoMappingEnumBehavior.cs ├── Metadata/ │ └── AssociationReflection.cs ├── Querying/ │ ├── SqlBuilderBehavior/ │ │ ├── BasicTests.cs │ │ ├── ConditionalAppendTests.cs │ │ ├── ConditionalClauseTests.cs │ │ ├── ExtensibilityTests.cs │ │ └── ValuesClauseTests.cs │ ├── SqlSetAnnotatedBehavior/ │ │ ├── BasicTests.cs │ │ └── IncludeTests.cs │ ├── SqlSetAsyncBehavior.cs │ ├── SqlSetBehavior.cs │ ├── SqlSetBehaviorForSqlServer.cs │ └── SqlTableBehavior.cs └── TestUtil.cs ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto # Custom for Visual Studio *.cs diff=csharp *.sln merge=union *.csproj merge=union *.vbproj merge=union *.fsproj merge=union *.dbproj merge=union # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: maxtoroq ================================================ FILE: .gitignore ================================================ /.vs/ /.nuget/ /packages/ /docs/api/_toc.xml [Bb]in [Oo]bj [Tt]est[Rr]esults *.suo *.user ================================================ FILE: .gitmodules ================================================ [submodule "build/sandcastle-md"] path = build/sandcastle-md url = https://github.com/maxtoroq/sandcastle-md.git ================================================ FILE: CHANGES.md ================================================ This page has moved [here](https://maxtoroq.github.io/DbExtensions/docs/7/changes.html). ================================================ FILE: DbExtensions.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.11.35222.181 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbExtensions", "src\DbExtensions\DbExtensions.csproj", "{0C0CB7A6-FDBA-49A0-8FA9-A35EFFFDE34D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0CD55BAA-00D6-4D14-AF01-B2ECC3F8E092}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{CDC6A939-6F5A-4CF5-ABDB-A2F87513A769}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbExtensions.Tests", "tests\DbExtensions.Tests\DbExtensions.Tests.csproj", "{ABB8412B-D292-4393-BB6D-F0241C41D198}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{A1718337-F793-499A-A4D1-5A6CF5F265DA}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.CSharp", "samples\CSharp\Samples.CSharp.csproj", "{CC01AB1C-A3CD-4E56-9AF0-8E4FD2000CE0}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.App", "samples\App\Samples.App.csproj", "{0ECA5137-1C9A-46BB-B5EB-ED87F0678FB4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbExtensions.SqlBuilder", "src\DbExtensions.SqlBuilder\DbExtensions.SqlBuilder.csproj", "{07B53903-2EB1-4E69-98A2-84069197ADB2}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbExtensions.SqlSet", "src\DbExtensions.SqlSet\DbExtensions.SqlSet.csproj", "{75C3AEF3-213C-494A-97FA-D4DCA76FA94A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbExtensions-QE", "src\DbExtensions-QE\DbExtensions-QE.csproj", "{731E7958-87D2-4C2F-9D59-6308D1553F53}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0C0CB7A6-FDBA-49A0-8FA9-A35EFFFDE34D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0C0CB7A6-FDBA-49A0-8FA9-A35EFFFDE34D}.Debug|Any CPU.Build.0 = Debug|Any CPU {0C0CB7A6-FDBA-49A0-8FA9-A35EFFFDE34D}.Release|Any CPU.ActiveCfg = Release|Any CPU {0C0CB7A6-FDBA-49A0-8FA9-A35EFFFDE34D}.Release|Any CPU.Build.0 = Release|Any CPU {ABB8412B-D292-4393-BB6D-F0241C41D198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ABB8412B-D292-4393-BB6D-F0241C41D198}.Debug|Any CPU.Build.0 = Debug|Any CPU {ABB8412B-D292-4393-BB6D-F0241C41D198}.Release|Any CPU.ActiveCfg = Release|Any CPU {ABB8412B-D292-4393-BB6D-F0241C41D198}.Release|Any CPU.Build.0 = Release|Any CPU {CC01AB1C-A3CD-4E56-9AF0-8E4FD2000CE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CC01AB1C-A3CD-4E56-9AF0-8E4FD2000CE0}.Debug|Any CPU.Build.0 = Debug|Any CPU {CC01AB1C-A3CD-4E56-9AF0-8E4FD2000CE0}.Release|Any CPU.ActiveCfg = Release|Any CPU {CC01AB1C-A3CD-4E56-9AF0-8E4FD2000CE0}.Release|Any CPU.Build.0 = Release|Any CPU {0ECA5137-1C9A-46BB-B5EB-ED87F0678FB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0ECA5137-1C9A-46BB-B5EB-ED87F0678FB4}.Debug|Any CPU.Build.0 = Debug|Any CPU {0ECA5137-1C9A-46BB-B5EB-ED87F0678FB4}.Release|Any CPU.ActiveCfg = Release|Any CPU {0ECA5137-1C9A-46BB-B5EB-ED87F0678FB4}.Release|Any CPU.Build.0 = Release|Any CPU {07B53903-2EB1-4E69-98A2-84069197ADB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {07B53903-2EB1-4E69-98A2-84069197ADB2}.Debug|Any CPU.Build.0 = Debug|Any CPU {07B53903-2EB1-4E69-98A2-84069197ADB2}.Release|Any CPU.ActiveCfg = Release|Any CPU {07B53903-2EB1-4E69-98A2-84069197ADB2}.Release|Any CPU.Build.0 = Release|Any CPU {75C3AEF3-213C-494A-97FA-D4DCA76FA94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {75C3AEF3-213C-494A-97FA-D4DCA76FA94A}.Debug|Any CPU.Build.0 = Debug|Any CPU {75C3AEF3-213C-494A-97FA-D4DCA76FA94A}.Release|Any CPU.ActiveCfg = Release|Any CPU {75C3AEF3-213C-494A-97FA-D4DCA76FA94A}.Release|Any CPU.Build.0 = Release|Any CPU {731E7958-87D2-4C2F-9D59-6308D1553F53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {731E7958-87D2-4C2F-9D59-6308D1553F53}.Debug|Any CPU.Build.0 = Debug|Any CPU {731E7958-87D2-4C2F-9D59-6308D1553F53}.Release|Any CPU.ActiveCfg = Release|Any CPU {731E7958-87D2-4C2F-9D59-6308D1553F53}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {0C0CB7A6-FDBA-49A0-8FA9-A35EFFFDE34D} = {0CD55BAA-00D6-4D14-AF01-B2ECC3F8E092} {ABB8412B-D292-4393-BB6D-F0241C41D198} = {CDC6A939-6F5A-4CF5-ABDB-A2F87513A769} {CC01AB1C-A3CD-4E56-9AF0-8E4FD2000CE0} = {A1718337-F793-499A-A4D1-5A6CF5F265DA} {0ECA5137-1C9A-46BB-B5EB-ED87F0678FB4} = {A1718337-F793-499A-A4D1-5A6CF5F265DA} {07B53903-2EB1-4E69-98A2-84069197ADB2} = {0CD55BAA-00D6-4D14-AF01-B2ECC3F8E092} {75C3AEF3-213C-494A-97FA-D4DCA76FA94A} = {0CD55BAA-00D6-4D14-AF01-B2ECC3F8E092} {731E7958-87D2-4C2F-9D59-6308D1553F53} = {0CD55BAA-00D6-4D14-AF01-B2ECC3F8E092} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {96FE150F-41AE-4AB7-AA87-2B8D278F1FF3} EndGlobalSection EndGlobal ================================================ FILE: LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: NOTICE.xml ================================================  DbExtensions https://maxtoroq.github.io/DbExtensions/ 2009-2025 Max Toro Q. Max Toro Q. .NET Framework https://github.com/Microsoft/referencesource Microsoft Corporation ================================================ FILE: README.md ================================================ [DbExtensions][1] — The SQL framework for .NET ============================================== DbExtensions is a data-access framework with a strong focus on **query composition, granularity and code aesthetics**. It supports both POCO and dynamic (untyped) mapping. See the [project home][1] and the [documentation][2] for more information. [![Build status](https://ci.appveyor.com/api/projects/status/qw9hoyur7yvlpi8y/branch/v7?svg=true)](https://ci.appveyor.com/project/maxtoroq/dbextensions/branch/v7) ![Tests](https://img.shields.io/appveyor/tests/maxtoroq/DbExtensions/v7) [1]: https://maxtoroq.github.io/DbExtensions/ [2]: https://maxtoroq.github.io/DbExtensions/docs/7/ ================================================ FILE: appveyor.yml ================================================ image: Visual Studio 2022 before_build: - cmd: MSBuild -t:restore version: '{build}' build: verbosity: minimal ================================================ FILE: build/.gitignore ================================================ /api-docs/ /EWSoftware.SHFB/ /EWSoftware.SHFB.*/ /nupkg/ ================================================ FILE: build/DbExtensions.shfbproj ================================================  $(MSBuildThisFileDirectory)\EWSoftware.SHFB\tools\ Debug AnyCPU 2.0 {e4c3bd2c-c9c8-4484-bc16-0d4a5f6dfcd3} 2017.9.26.0 Documentation Documentation Documentation api-docs\html\ Documentation en-US Website False DbExtensions MemberName Top C# False DbExtensions DbExtensions is a data-access framework with a strong focus on query composition, granularity and code aesthetics. <see cref="T:DbExtensions.Database"/> is the entry point of the <see cref="N:DbExtensions"/> API. True VS2013 False AboveNamespaces OnlyWarningsAndErrors False .NET Core/.NET Standard/.NET 5.0+ False False False AutoDocumentCtors, AutoDocumentDispose 2 False DbExtensions Namespaces InheritedMembers, Protected, SealedProtected, NonBrowsable ================================================ FILE: build/build-docs.ps1 ================================================ param([string]$ProjectName = "DbExtensions", [switch]$NoBuildProj, [switch]$XmlOnly) $ErrorActionPreference = "Stop" Push-Location (Split-Path $script:MyInvocation.MyCommand.Path) try { $nuget = .\ensure-nuget.ps1 if (-not (Test-Path EWSoftware.SHFB -PathType Container)) { &$nuget install EWSoftware.SHFB -Version 2025.3.22 -ExcludeVersion } if (-not (Test-Path EWSoftware.SHFB.NET -PathType Container)) { &$nuget install EWSoftware.SHFB.NET -Version 5.0.0.2 -ExcludeVersion } if (-not $NoBuildProj) { MSBuild ..\src\$ProjectName\$ProjectName.csproj /v:minimal /p:Configuration=Release } MSBuild DbExtensions.shfbproj /v:minimal /p:ProjectName=$ProjectName if (-not $XmlOnly) { .\sandcastle-md\packages\restore.ps1 MSBuild sandcastle-md\sandcastle-md.sln /v:minimal if (Test-Path ..\docs\api -PathType Container) { rm ..\docs\api -Recurse } sandcastle-md\src\sandcastle-md\bin\Debug\sandcastle-md.exe api-docs\html ..\docs\api ` --remove-assembly-name ` --remove-assembly-version ` --exclude-icons } } finally { Pop-Location } ================================================ FILE: build/ensure-nuget.ps1 ================================================ $ErrorActionPreference = "Stop" Push-Location (Split-Path $script:MyInvocation.MyCommand.Path) $nuget = "..\.nuget\nuget.exe" try { $nugetDir = Split-Path $nuget if (-not (Test-Path $nugetDir -PathType Container)) { md $nugetDir | Out-Null } if (-not (Test-Path $nuget -PathType Leaf)) { Write-Host "Downloading NuGet..." Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile $nuget } Resolve-Path $nuget } finally { Pop-Location } ================================================ FILE: build/release.ps1 ================================================ param( [Parameter(Mandatory=$true)][Version]$AssemblyVersion, [Parameter(Mandatory=$true)][Version]$PackageVersion, [Parameter()][string]$PreRelease ) $ErrorActionPreference = "Stop" Push-Location (Split-Path $script:MyInvocation.MyCommand.Path) $solutionPath = Resolve-Path .. $configuration = "Release" function ProjectPath([string]$projName) { Resolve-Path $solutionPath\src\$projName } function ProjectFile([string]$projName) { $projPath = ProjectPath $projName return "$projPath\$projName.csproj" } function BuildProj([string]$projName, [string]$target) { $pack = $target -eq "Pack" MSBuild $(ProjectFile($projName)) /t:$target /v:minimal ` /p:NoBuild=$pack ` /p:Configuration=$configuration ` /p:PackageOutputPath=$outputPath ` /p:AssemblyVersion=$AssemblyVersion ` /p:FileVersion=$PackageVersion ` /p:VersionPrefix=$PackageVersion ` /p:VersionSuffix=$PreRelease ` /p:ContinuousIntegrationBuild=true ` /p:GenerateDocumentationFile=$(-not $pack) ` /p:Authors=$($notice.authors) ` /p:Product=$($notice.work) ` /p:Copyright=$($notice.copyright) ` /p:Company=$($notice.website) ` /p:PackageLicenseExpression=$($notice.license.name) ` /p:PackageProjectUrl=$($notice.website) ` /p:PackageReleaseNotes="For a list of changes see $($notice.website)docs/7/changes.html" ` /p:RepositoryBranch=$(git branch --show-current) } function NuPack([string]$projName) { BuildProj $projName "Build" | Out-Host .\build-docs.ps1 -ProjectName $projName -NoBuildProj -XmlOnly | Out-Host BuildProj $projName "Pack" | Out-Host return Join-Path $outputPath "$projName.$pkgVer.nupkg" } function Prompt-Choices($Choices=("&Yes", "&No"), [string]$Title="Confirm", [string]$Message="Are you sure?", [int]$Default=0) { $choicesArr = [Management.Automation.Host.ChoiceDescription[]] ` ($Choices | % {New-Object Management.Automation.Host.ChoiceDescription $_}) return $host.ui.PromptForChoice($Title, $Message, $choicesArr, $Default) } try { [xml]$noticeDoc = Get-Content $solutionPath\NOTICE.xml $notice = $noticeDoc.DocumentElement if (-not (Test-Path nupkg -PathType Container)) { md nupkg | Out-Null } $outputPath = Resolve-Path nupkg $pkgVer = $PackageVersion.ToString(3) if ($PreRelease) { $pkgVer = $pkgVer + "-" + $PreRelease } $newTag = "v$pkgVer" MSBuild $solutionPath\DbExtensions.sln -t:Restore $newPackages = (NuPack DbExtensions), (NuPack DbExtensions-QE) if ((Prompt-Choices -Message "Create tag $newTag ?" -Default 1) -eq 0) { git tag -a $newTag -m $newTag Write-Warning "Created tag: $newTag" if ((Prompt-Choices -Message "Push package(s) to gallery?" -Default 1) -eq 0) { foreach ($pkgPath in $newPackages) { dotnet nuget push $pkgPath --source nuget.org } } if ((Prompt-Choices -Message "Push new tag $newTag to origin?" -Default 1) -eq 0) { git push origin $newTag } } } finally { Pop-Location } ================================================ FILE: docs/README.md ================================================ Documentation has moved [here](https://maxtoroq.github.io/DbExtensions/docs/7/). ================================================ FILE: docs/SqlBuilder.md ================================================ This page has moved [here](https://maxtoroq.github.io/DbExtensions/docs/7/SqlBuilder.html). ================================================ FILE: docs/SqlSet.md ================================================ This page has moved [here](https://maxtoroq.github.io/DbExtensions/docs/7/SqlSet.html). ================================================ FILE: docs/api/DbExtensions/AssociationAttribute/Name.md ================================================ AssociationAttribute.Name Property ================================== Gets or sets the name of a constraint. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string? Name { get; set; } ``` #### Property Value [String][2] See Also -------- #### Reference [AssociationAttribute Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/AssociationAttribute/OtherKey.md ================================================ AssociationAttribute.OtherKey Property ====================================== Gets or sets one or more members of the target entity class as key values on the other side of the association. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string? OtherKey { get; set; } ``` #### Property Value [String][2] See Also -------- #### Reference [AssociationAttribute Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/AssociationAttribute/README.md ================================================ AssociationAttribute Class ========================== Designates a property to represent a database association, such as a foreign key relationship. Inheritance Hierarchy --------------------- [System.Object][1]   [System.Attribute][2]     **DbExtensions.AssociationAttribute** **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public sealed class AssociationAttribute : Attribute ``` The **AssociationAttribute** type exposes the following members. Constructors ------------ | Name | Description | | ------------------------- | ---------------------------------------------------------------- | | [AssociationAttribute][4] | Initializes a new instance of the **AssociationAttribute** class | Properties ---------- | Name | Description | | ------------- | --------------------------------------------------------------------------------------------------------------- | | [Name][5] | Gets or sets the name of a constraint. | | [OtherKey][6] | Gets or sets one or more members of the target entity class as key values on the other side of the association. | | [ThisKey][7] | Gets or sets members of this entity class to represent the key values on this side of the association. | See Also -------- #### Reference [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.object [2]: https://learn.microsoft.com/dotnet/api/system.attribute [3]: ../README.md [4]: _ctor.md [5]: Name.md [6]: OtherKey.md [7]: ThisKey.md ================================================ FILE: docs/api/DbExtensions/AssociationAttribute/ThisKey.md ================================================ AssociationAttribute.ThisKey Property ===================================== Gets or sets members of this entity class to represent the key values on this side of the association. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string? ThisKey { get; set; } ``` #### Property Value [String][2] See Also -------- #### Reference [AssociationAttribute Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/AssociationAttribute/_ctor.md ================================================ AssociationAttribute Constructor ================================ Initializes a new instance of the [AssociationAttribute][1] class **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public AssociationAttribute() ``` See Also -------- #### Reference [AssociationAttribute Class][1] [DbExtensions Namespace][2] [1]: README.md [2]: ../README.md ================================================ FILE: docs/api/DbExtensions/AutoSync/README.md ================================================ AutoSync Enumeration ==================== Used to specify for during INSERT and UPDATE operations when a data member should be read back after the operation completes. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public enum AutoSync ``` Members ------- | Member name | Value | Description | | ----------- | ----- | ------------------------------------------------- | | Default | 0 | Automatically selects the value. | | Always | 1 | Always returns the value. | | Never | 2 | Never returns the value. | | OnInsert | 3 | Returns the value only after an INSERT operation. | | OnUpdate | 4 | Returns the value only after an UPDATE operation. | See Also -------- #### Reference [DbExtensions Namespace][1] [1]: ../README.md ================================================ FILE: docs/api/DbExtensions/ChangeConflictException/README.md ================================================ ChangeConflictException Class ============================= An exception that is thrown when a concurrency violation is encountered while saving to the database. A concurrency violation occurs when an unexpected number of rows are affected during save. This is usually because the data in the database has been modified since it was loaded into memory. Inheritance Hierarchy --------------------- [System.Object][1]   [System.Exception][2]     **DbExtensions.ChangeConflictException** **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public sealed class ChangeConflictException : Exception ``` The **ChangeConflictException** type exposes the following members. Constructors ------------ | Name | Description | | ---------------------------- | --------------------------------------------------------------------------------------------------- | | [ChangeConflictException][4] | Initializes a new instance of the **ChangeConflictException** class with a specified error message. | See Also -------- #### Reference [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.object [2]: https://learn.microsoft.com/dotnet/api/system.exception [3]: ../README.md [4]: _ctor.md ================================================ FILE: docs/api/DbExtensions/ChangeConflictException/_ctor.md ================================================ ChangeConflictException Constructor =================================== Initializes a new instance of the [ChangeConflictException][1] class with a specified error message. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ChangeConflictException( string message ) ``` #### Parameters ##### *message*  [String][3] The message that describes the error. See Also -------- #### Reference [ChangeConflictException Class][1] [DbExtensions Namespace][2] [1]: README.md [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.string ================================================ FILE: docs/api/DbExtensions/ColumnAttribute/AutoSync.md ================================================ ColumnAttribute.AutoSync Property ================================= Gets or sets the [AutoSync][1] enumeration. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public AutoSync AutoSync { get; set; } ``` #### Property Value [AutoSync][1] See Also -------- #### Reference [ColumnAttribute Class][3] [DbExtensions Namespace][2] [1]: ../AutoSync/README.md [2]: ../README.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/ColumnAttribute/ConvertTo.md ================================================ ColumnAttribute.ConvertTo Property ================================== Gets or sets the type to convert this member to before sending to the database. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public Type? ConvertTo { get; set; } ``` #### Property Value [Type][2] See Also -------- #### Reference [ColumnAttribute Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.type [3]: README.md ================================================ FILE: docs/api/DbExtensions/ColumnAttribute/IsDbGenerated.md ================================================ ColumnAttribute.IsDbGenerated Property ====================================== Gets or sets whether a column contains values that the database auto-generates. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool IsDbGenerated { get; set; } ``` #### Property Value [Boolean][2] See Also -------- #### Reference [ColumnAttribute Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.boolean [3]: README.md ================================================ FILE: docs/api/DbExtensions/ColumnAttribute/IsPrimaryKey.md ================================================ ColumnAttribute.IsPrimaryKey Property ===================================== Gets or sets whether this class member represents a column that is part or all of the primary key of the table. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool IsPrimaryKey { get; set; } ``` #### Property Value [Boolean][2] See Also -------- #### Reference [ColumnAttribute Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.boolean [3]: README.md ================================================ FILE: docs/api/DbExtensions/ColumnAttribute/IsVersion.md ================================================ ColumnAttribute.IsVersion Property ================================== Gets or sets whether the column type of the member is a database timestamp or version number. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool IsVersion { get; set; } ``` #### Property Value [Boolean][2] See Also -------- #### Reference [ColumnAttribute Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.boolean [3]: README.md ================================================ FILE: docs/api/DbExtensions/ColumnAttribute/Name.md ================================================ ColumnAttribute.Name Property ============================= Gets or sets the name of a column. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string? Name { get; set; } ``` #### Property Value [String][2] See Also -------- #### Reference [ColumnAttribute Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/ColumnAttribute/README.md ================================================ ColumnAttribute Class ===================== Associates a property with a column in a database table. Inheritance Hierarchy --------------------- [System.Object][1]   [System.Attribute][2]     **DbExtensions.ColumnAttribute** **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public sealed class ColumnAttribute : Attribute ``` The **ColumnAttribute** type exposes the following members. Constructors ------------ | Name | Description | | -------------------- | ----------------------------------------------------------- | | [ColumnAttribute][4] | Initializes a new instance of the **ColumnAttribute** class | Properties ---------- | Name | Description | | ------------------ | --------------------------------------------------------------------------------------------------------------- | | [AutoSync][5] | Gets or sets the [AutoSync][6] enumeration. | | [ConvertTo][7] | Gets or sets the type to convert this member to before sending to the database. | | [IsDbGenerated][8] | Gets or sets whether a column contains values that the database auto-generates. | | [IsPrimaryKey][9] | Gets or sets whether this class member represents a column that is part or all of the primary key of the table. | | [IsVersion][10] | Gets or sets whether the column type of the member is a database timestamp or version number. | | [Name][11] | Gets or sets the name of a column. | See Also -------- #### Reference [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.object [2]: https://learn.microsoft.com/dotnet/api/system.attribute [3]: ../README.md [4]: _ctor.md [5]: AutoSync.md [6]: ../AutoSync/README.md [7]: ConvertTo.md [8]: IsDbGenerated.md [9]: IsPrimaryKey.md [10]: IsVersion.md [11]: Name.md ================================================ FILE: docs/api/DbExtensions/ColumnAttribute/_ctor.md ================================================ ColumnAttribute Constructor =========================== Initializes a new instance of the [ColumnAttribute][1] class **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ColumnAttribute() ``` See Also -------- #### Reference [ColumnAttribute Class][1] [DbExtensions Namespace][2] [1]: README.md [2]: ../README.md ================================================ FILE: docs/api/DbExtensions/ComplexPropertyAttribute/Name.md ================================================ ComplexPropertyAttribute.Name Property ====================================== The base name for the columns on the complex property. The default is the property name. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string? Name { get; set; } ``` #### Property Value [String][2] See Also -------- #### Reference [ComplexPropertyAttribute Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/ComplexPropertyAttribute/README.md ================================================ ComplexPropertyAttribute Class ============================== Designates a property as a complex property that groups columns of a table that share the same base name. Inheritance Hierarchy --------------------- [System.Object][1]   [System.Attribute][2]     **DbExtensions.ComplexPropertyAttribute** **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public sealed class ComplexPropertyAttribute : Attribute ``` The **ComplexPropertyAttribute** type exposes the following members. Constructors ------------ | Name | Description | | ----------------------------- | -------------------------------------------------------------------- | | [ComplexPropertyAttribute][4] | Initializes a new instance of the **ComplexPropertyAttribute** class | Properties ---------- | Name | Description | | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Name][5] | The base name for the columns on the complex property. The default is the property name. | | [Separator][6] | The separator to use between the base name and the complex property's columns. The default is null, which means the separator is taken from [DatabaseConfiguration.DefaultComplexPropertySeparator][7]. To use no separator and override the default configuration, use an empty [String][8]. | See Also -------- #### Reference [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.object [2]: https://learn.microsoft.com/dotnet/api/system.attribute [3]: ../README.md [4]: _ctor.md [5]: Name.md [6]: Separator.md [7]: ../DatabaseConfiguration/DefaultComplexPropertySeparator.md [8]: https://learn.microsoft.com/dotnet/api/system.string ================================================ FILE: docs/api/DbExtensions/ComplexPropertyAttribute/Separator.md ================================================ ComplexPropertyAttribute.Separator Property =========================================== The separator to use between the base name and the complex property's columns. The default is null, which means the separator is taken from [DatabaseConfiguration.DefaultComplexPropertySeparator][1]. To use no separator and override the default configuration, use an empty [String][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string? Separator { get; set; } ``` #### Property Value [String][2] See Also -------- #### Reference [ComplexPropertyAttribute Class][4] [DbExtensions Namespace][3] [1]: ../DatabaseConfiguration/DefaultComplexPropertySeparator.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: ../README.md [4]: README.md ================================================ FILE: docs/api/DbExtensions/ComplexPropertyAttribute/_ctor.md ================================================ ComplexPropertyAttribute Constructor ==================================== Initializes a new instance of the [ComplexPropertyAttribute][1] class **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ComplexPropertyAttribute() ``` See Also -------- #### Reference [ComplexPropertyAttribute Class][1] [DbExtensions Namespace][2] [1]: README.md [2]: ../README.md ================================================ FILE: docs/api/DbExtensions/Database/Add.md ================================================ Database.Add Method =================== Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public void Add( Object entity ) ``` #### Parameters ##### *entity*  [Object][2] The object whose INSERT command is to be executed. This parameter is named entity for consistency with the other CRUD methods, but in this case it doesn't need to be an actual entity, which means it doesn't need to have a primary key. Remarks ------- This method is a shortcut for `db.Table(entity.GetType()).Add(entity)`. See Also -------- #### Reference [Database Class][3] [DbExtensions Namespace][1] [SqlTable.Add(Object)][4] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: README.md [4]: ../SqlTable/Add.md ================================================ FILE: docs/api/DbExtensions/Database/AddAsync.md ================================================ Database.AddAsync Method ======================== Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask AddAsync( Object entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [Object][2] The object whose INSERT command is to be executed. This parameter is named entity for consistency with the other CRUD methods, but in this case it doesn't need to be an actual entity, which means it doesn't need to have a primary key. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5] Remarks ------- This method is a shortcut for `await db.Table(entity.GetType()).AddAsync(entity, cancellationToken)`. See Also -------- #### Reference [Database Class][6] [DbExtensions Namespace][1] [SqlTable.AddAsync(Object, CancellationToken)][7] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [6]: README.md [7]: ../SqlTable/AddAsync.md ================================================ FILE: docs/api/DbExtensions/Database/AsyncMap.md ================================================ Database.AsyncMap(SqlBuilder) Method ==================================== Maps the results of the *query* to dynamic objects. The query is deferred-executed. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | **AsyncMap(SqlBuilder)** | Maps the results of the *query* to dynamic objects. The query is deferred-executed. | | [AsyncMap(SqlBuilder, Type)][2] | Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. | | [AsyncMap<TResult>(SqlBuilder)][3] | Maps the results of the *query* to TResult objects. The query is deferred-executed. | | [AsyncMap<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][4] | Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. | Syntax ------ ```csharp public IAsyncEnumerable AsyncMap( SqlBuilder query ) ``` #### Parameters ##### *query*  [SqlBuilder][5] The query. #### Return Value [IAsyncEnumerable][6]<[Object][7]> The results of the query as dynamic objects. See Also -------- #### Reference [Database Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: AsyncMap_1.md [3]: AsyncMap__1.md [4]: AsyncMap__1_1.md [5]: ../SqlBuilder/README.md [6]: https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerable-1 [7]: https://learn.microsoft.com/dotnet/api/system.object [8]: README.md ================================================ FILE: docs/api/DbExtensions/Database/AsyncMap_1.md ================================================ Database.AsyncMap(SqlBuilder, Type) Method ========================================== Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | [AsyncMap(SqlBuilder)][2] | Maps the results of the *query* to dynamic objects. The query is deferred-executed. | | **AsyncMap(SqlBuilder, Type)** | Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. | | [AsyncMap<TResult>(SqlBuilder)][3] | Maps the results of the *query* to TResult objects. The query is deferred-executed. | | [AsyncMap<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][4] | Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. | Syntax ------ ```csharp public IAsyncEnumerable AsyncMap( SqlBuilder query, Type resultType ) ``` #### Parameters ##### *query*  [SqlBuilder][5] The query. ##### *resultType*  [Type][6] The type of objects to map the results to. #### Return Value [IAsyncEnumerable][7]<[Object][8]> The results of the query as objects of type specified by the *resultType* parameter. See Also -------- #### Reference [Database Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: AsyncMap.md [3]: AsyncMap__1.md [4]: AsyncMap__1_1.md [5]: ../SqlBuilder/README.md [6]: https://learn.microsoft.com/dotnet/api/system.type [7]: https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerable-1 [8]: https://learn.microsoft.com/dotnet/api/system.object [9]: README.md ================================================ FILE: docs/api/DbExtensions/Database/AsyncMap__1.md ================================================ Database.AsyncMap<TResult>(SqlBuilder) Method ================================================ Maps the results of the *query* to TResult objects. The query is deferred-executed. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | [AsyncMap(SqlBuilder)][2] | Maps the results of the *query* to dynamic objects. The query is deferred-executed. | | [AsyncMap(SqlBuilder, Type)][3] | Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. | | **AsyncMap<TResult>(SqlBuilder)** | Maps the results of the *query* to TResult objects. The query is deferred-executed. | | [AsyncMap<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][4] | Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. | Syntax ------ ```csharp public IAsyncEnumerable AsyncMap( SqlBuilder query ) ``` #### Parameters ##### *query*  [SqlBuilder][5] The query. #### Type Parameters ##### *TResult* The type of objects to map the results to. #### Return Value [IAsyncEnumerable][6]<**TResult**> The results of the query as TResult objects. See Also -------- #### Reference [Database Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: AsyncMap.md [3]: AsyncMap_1.md [4]: AsyncMap__1_1.md [5]: ../SqlBuilder/README.md [6]: https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerable-1 [7]: README.md ================================================ FILE: docs/api/DbExtensions/Database/AsyncMap__1_1.md ================================================ Database.AsyncMap<TResult>(SqlBuilder, Func<DbDataReader, TResult>) Method ================================================================================ Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | [AsyncMap(SqlBuilder)][2] | Maps the results of the *query* to dynamic objects. The query is deferred-executed. | | [AsyncMap(SqlBuilder, Type)][3] | Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. | | [AsyncMap<TResult>(SqlBuilder)][4] | Maps the results of the *query* to TResult objects. The query is deferred-executed. | | **AsyncMap<TResult>(SqlBuilder, Func<DbDataReader, TResult>)** | Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. | Syntax ------ ```csharp public IAsyncEnumerable AsyncMap( SqlBuilder query, Func mapper ) ``` #### Parameters ##### *query*  [SqlBuilder][5] The query. ##### *mapper*  [Func][6]<[DbDataReader][7], **TResult**> The delegate for creating TResult objects from an [DbDataReader][7] object. #### Type Parameters ##### *TResult* The type of objects to map the results to. #### Return Value [IAsyncEnumerable][8]<**TResult**> The results of the query as TResult objects. See Also -------- #### Reference [Database Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: AsyncMap.md [3]: AsyncMap_1.md [4]: AsyncMap__1.md [5]: ../SqlBuilder/README.md [6]: https://learn.microsoft.com/dotnet/api/system.func-2 [7]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [8]: https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerable-1 [9]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Configuration.md ================================================ Database.Configuration Property =============================== Provides access to configuration options for this instance. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public DatabaseConfiguration Configuration { get; } ``` #### Property Value [DatabaseConfiguration][2] See Also -------- #### Reference [Database Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: ../DatabaseConfiguration/README.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Connection.md ================================================ Database.Connection Property ============================ Gets the connection to associate with new commands. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public DbConnection Connection { get; } ``` #### Property Value [DbConnection][2] See Also -------- #### Reference [Database Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.data.common.dbconnection [3]: README.md ================================================ FILE: docs/api/DbExtensions/Database/CreateCommand.md ================================================ Database.CreateCommand Method ============================= Creates and returns a [DbCommand][1] object from the specified *sqlBuilder*. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public virtual DbCommand CreateCommand( SqlBuilder sqlBuilder ) ``` #### Parameters ##### *sqlBuilder*  [SqlBuilder][3] The [SqlBuilder][3] that provides the command's text and parameters. #### Return Value [DbCommand][1] A new [DbCommand][1] object with its [CommandText][4] property initialized with the *sqlBuilder*'s string representation, and its [Parameters][5] property is initialized with the values from the [ParameterValues][6] property of the *sqlBuilder* parameter. See Also -------- #### Reference [Database Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.data.common.dbcommand [2]: ../README.md [3]: ../SqlBuilder/README.md [4]: https://learn.microsoft.com/dotnet/api/system.data.common.dbcommand.commandtext [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbcommand.parameters [6]: ../SqlBuilder/ParameterValues.md [7]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Dispose.md ================================================ Database.Dispose Method ======================= Releases all resources used by the current instance of the [Database][1] class. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------- | ------------------------------------------------------------------------------- | | **Dispose()** | Releases all resources used by the current instance of the [Database][1] class. | | [Dispose(Boolean)][3] | Releases the resources used by this [Database][1] instance. | Syntax ------ ```csharp public void Dispose() ``` #### Implements [IDisposable.Dispose()][4] See Also -------- #### Reference [Database Class][1] [DbExtensions Namespace][2] [1]: README.md [2]: ../README.md [3]: Dispose_1.md [4]: https://learn.microsoft.com/dotnet/api/system.idisposable.dispose ================================================ FILE: docs/api/DbExtensions/Database/Dispose_1.md ================================================ Database.Dispose(Boolean) Method ================================ Releases the resources used by this [Database][1] instance. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------- | ------------------------------------------------------------------------------- | | [Dispose()][3] | Releases all resources used by the current instance of the [Database][1] class. | | **Dispose(Boolean)** | Releases the resources used by this [Database][1] instance. | Syntax ------ ```csharp protected virtual void Dispose( bool disposing ) ``` #### Parameters ##### *disposing*  [Boolean][4] `true` if this method is being called due to a call to [Dispose()][3]; otherwise, `false`. See Also -------- #### Reference [Database Class][1] [DbExtensions Namespace][2] [1]: README.md [2]: ../README.md [3]: Dispose.md [4]: https://learn.microsoft.com/dotnet/api/system.boolean ================================================ FILE: docs/api/DbExtensions/Database/EnsureConnectionOpen.md ================================================ Database.EnsureConnectionOpen Method ==================================== Opens [Connection][1] (if it's not open) and returns an [IDisposable][2] object you can use to close it (if it wasn't open). **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public IDisposable EnsureConnectionOpen() ``` #### Return Value [IDisposable][2] An [IDisposable][2] object to close the connection. Remarks ------- Use this method with the `using` statement in C# or Visual Basic to ensure that a block of code is always executed with an open connection. Example ------- ```csharp using (db.EnsureConnectionOpen()) { // Execute commands. } ``` See Also -------- #### Reference [Database Class][4] [DbExtensions Namespace][3] [1]: Connection.md [2]: https://learn.microsoft.com/dotnet/api/system.idisposable [3]: ../README.md [4]: README.md ================================================ FILE: docs/api/DbExtensions/Database/EnsureConnectionOpenAsync.md ================================================ Database.EnsureConnectionOpenAsync Method ========================================= Opens [Connection][1] (if it's not open) and returns an [IAsyncDisposable][2] object you can use to close it (if it wasn't open). **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask EnsureConnectionOpenAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[IAsyncDisposable][2]> An [IAsyncDisposable][2] object to close the connection. Remarks ------- Use this method with the `using` statement in C# or Visual Basic to ensure that a block of code is always executed with an open connection. Example ------- ```csharp await using (await db.EnsureConnectionOpenAsync()) { // Execute commands. } ``` See Also -------- #### Reference [Database Class][7] [DbExtensions Namespace][3] [1]: Connection.md [2]: https://learn.microsoft.com/dotnet/api/system.iasyncdisposable [3]: ../README.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: README.md ================================================ FILE: docs/api/DbExtensions/Database/EnsureInTransaction.md ================================================ Database.EnsureInTransaction Method =================================== Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | **EnsureInTransaction()** | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | | [EnsureInTransaction(IsolationLevel)][2] | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | Syntax ------ ```csharp public DbTransaction EnsureInTransaction() ``` #### Return Value [DbTransaction][3] A virtual transaction you can use to ensure a code block is always executed in a transaction, new or existing. Remarks ------- This method returns a virtual transaction that wraps an existing or new transaction. By calling [Commit()][4] on the returned object, this object will then call [Commit()][4] on the wrapped transaction if the transaction was just created, or do nothing if it was previously created. Example ------- Calls to this method can be nested, like in the following example: ```csharp void DoSomething() { using (var tx = this.db.EnsureInTransaction()) { // Execute commands DoSomethingElse(); tx.Commit(); } } void DoSomethingElse() { using (var tx = this.db.EnsureInTransaction()) { // Execute commands tx.Commit(); } } ``` See Also -------- #### Reference [Database Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: EnsureInTransaction_1.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbtransaction [4]: https://learn.microsoft.com/dotnet/api/system.data.common.dbtransaction.commit [5]: README.md ================================================ FILE: docs/api/DbExtensions/Database/EnsureInTransactionAsync.md ================================================ Database.EnsureInTransactionAsync(IsolationLevel, CancellationToken) Method =========================================================================== Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | [EnsureInTransactionAsync(CancellationToken)][2] | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | | **EnsureInTransactionAsync(IsolationLevel, CancellationToken)** | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | Syntax ------ ```csharp public virtual ValueTask EnsureInTransactionAsync( IsolationLevel isolationLevel, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *isolationLevel*  [IsolationLevel][3] Specifies the isolation level for the transaction. This parameter is ignored when using an existing transaction. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[DbTransaction][7]> A virtual transaction you can use to ensure a code block is always executed in a transaction, new or existing. Remarks ------- This method returns a virtual transaction that wraps an existing or new transaction. By calling [Commit()][8] on the returned object, this object will then call [Commit()][8] on the wrapped transaction if the transaction was just created, or do nothing if it was previously created. Example ------- Calls to this method can be nested, like in the following example: ```csharp async Task DoSomething() { await using (var tx = await this.db.EnsureInTransactionAsync()) { // Execute commands await DoSomethingElse(); await tx.CommitAsync(); } } async Task DoSomethingElse() { await using (var tx = await this.db.EnsureInTransactionAsync()) { // Execute commands await tx.CommitAsync(); } } ``` See Also -------- #### Reference [Database Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: EnsureInTransactionAsync_1.md [3]: https://learn.microsoft.com/dotnet/api/system.data.isolationlevel [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.data.common.dbtransaction [8]: https://learn.microsoft.com/dotnet/api/system.data.common.dbtransaction.commit [9]: README.md ================================================ FILE: docs/api/DbExtensions/Database/EnsureInTransactionAsync_1.md ================================================ Database.EnsureInTransactionAsync(CancellationToken) Method =========================================================== Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | **EnsureInTransactionAsync(CancellationToken)** | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | | [EnsureInTransactionAsync(IsolationLevel, CancellationToken)][2] | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | Syntax ------ ```csharp public ValueTask EnsureInTransactionAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[DbTransaction][6]> A virtual transaction you can use to ensure a code block is always executed in a transaction, new or existing. Remarks ------- This method returns a virtual transaction that wraps an existing or new transaction. By calling [Commit()][7] on the returned object, this object will then call [Commit()][7] on the wrapped transaction if the transaction was just created, or do nothing if it was previously created. Example ------- Calls to this method can be nested, like in the following example: ```csharp async Task DoSomething() { await using (var tx = await this.db.EnsureInTransactionAsync()) { // Execute commands await DoSomethingElse(); await tx.CommitAsync(); } } async Task DoSomethingElse() { await using (var tx = await this.db.EnsureInTransactionAsync()) { // Execute commands await tx.CommitAsync(); } } ``` See Also -------- #### Reference [Database Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: EnsureInTransactionAsync.md [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.data.common.dbtransaction [7]: https://learn.microsoft.com/dotnet/api/system.data.common.dbtransaction.commit [8]: README.md ================================================ FILE: docs/api/DbExtensions/Database/EnsureInTransaction_1.md ================================================ Database.EnsureInTransaction(IsolationLevel) Method =================================================== Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | [EnsureInTransaction()][2] | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | | **EnsureInTransaction(IsolationLevel)** | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | Syntax ------ ```csharp public virtual DbTransaction EnsureInTransaction( IsolationLevel isolationLevel ) ``` #### Parameters ##### *isolationLevel*  [IsolationLevel][3] Specifies the isolation level for the transaction. This parameter is ignored when using an existing transaction. #### Return Value [DbTransaction][4] A virtual transaction you can use to ensure a code block is always executed in a transaction, new or existing. Remarks ------- This method returns a virtual transaction that wraps an existing or new transaction. By calling [Commit()][5] on the returned object, this object will then call [Commit()][5] on the wrapped transaction if the transaction was just created, or do nothing if it was previously created. Example ------- Calls to this method can be nested, like in the following example: ```csharp void DoSomething() { using (var tx = this.db.EnsureInTransaction()) { // Execute commands DoSomethingElse(); tx.Commit(); } } void DoSomethingElse() { using (var tx = this.db.EnsureInTransaction()) { // Execute commands tx.Commit(); } } ``` See Also -------- #### Reference [Database Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: EnsureInTransaction.md [3]: https://learn.microsoft.com/dotnet/api/system.data.isolationlevel [4]: https://learn.microsoft.com/dotnet/api/system.data.common.dbtransaction [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbtransaction.commit [6]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Execute.md ================================================ Database.Execute Method ======================= Executes the *nonQuery* command. Optionally uses a transaction and validates affected records value before committing. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public int Execute( SqlBuilder nonQuery, int affect = -1, bool exact = false ) ``` #### Parameters ##### *nonQuery*  [SqlBuilder][2] The non-query command to execute. ##### *affect*  [Int32][3]  (Optional) The number of records the command should affect. This value is ignored if less or equal to -1. ##### *exact*  [Boolean][4]  (Optional) `true` if the number of affected records should exactly match *affect*; `false` if a lower number is acceptable. #### Return Value [Int32][3] The number of affected records. Exceptions ---------- | Exception | Condition | | ---------------------------- | -------------------------------------------------------- | | [ChangeConflictException][5] | The number of affected records is not equal to *affect*. | See Also -------- #### Reference [Database Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: ../SqlBuilder/README.md [3]: https://learn.microsoft.com/dotnet/api/system.int32 [4]: https://learn.microsoft.com/dotnet/api/system.boolean [5]: ../ChangeConflictException/README.md [6]: README.md ================================================ FILE: docs/api/DbExtensions/Database/ExecuteAsync.md ================================================ Database.ExecuteAsync Method ============================ Executes the *nonQuery* command. Optionally uses a transaction and validates affected records value before committing. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask ExecuteAsync( SqlBuilder nonQuery, int affect = -1, bool exact = false, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *nonQuery*  [SqlBuilder][2] The non-query command to execute. ##### *affect*  [Int32][3]  (Optional) The number of records the command should affect. This value is ignored if less or equal to -1. ##### *exact*  [Boolean][4]  (Optional) `true` if the number of affected records should exactly match *affect*; `false` if a lower number is acceptable. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[Int32][3]> The number of affected records. Exceptions ---------- | Exception | Condition | | ---------------------------- | -------------------------------------------------------- | | [ChangeConflictException][8] | The number of affected records is not equal to *affect*. | See Also -------- #### Reference [Database Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: ../SqlBuilder/README.md [3]: https://learn.microsoft.com/dotnet/api/system.int32 [4]: https://learn.microsoft.com/dotnet/api/system.boolean [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: ../ChangeConflictException/README.md [9]: README.md ================================================ FILE: docs/api/DbExtensions/Database/FindAsync__1.md ================================================ Database.FindAsync<TEntity> Method ===================================== Gets the entity whose primary key matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask FindAsync( Object id, CancellationToken cancellationToken = default ) where TEntity : class ``` #### Parameters ##### *id*  [Object][2] The primary key value. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Type Parameters ##### *TEntity* The type of the entity. #### Return Value [ValueTask][5]<**TEntity**> The entity whose primary key matches the *id* parameter, or null if the *id* does not exist. Remarks ------- This method is a shortcut for `await db.Table().FindAsync(id, cancellationToken)`. See Also -------- #### Reference [Database Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Find__1.md ================================================ Database.Find<TEntity> Method ================================ Gets the entity whose primary key matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public TEntity Find( Object id ) where TEntity : class ``` #### Parameters ##### *id*  [Object][2] The primary key value. #### Type Parameters ##### *TEntity* The type of the entity. #### Return Value **TEntity** The entity whose primary key matches the *id* parameter, or null if the *id* does not exist. Remarks ------- This method is a shortcut for `db.Table().Find(id)`. See Also -------- #### Reference [Database Class][3] [DbExtensions Namespace][1] [SqlSet<TResult>.Find(Object)][4] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: README.md [4]: ../SqlSet_1/Find.md ================================================ FILE: docs/api/DbExtensions/Database/From.md ================================================ Database.From(String) Method ============================ Creates and returns a new [SqlSet][1] using the provided table name. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------- | -------------------------------------------------------------------------------- | | **From(String)** | Creates and returns a new [SqlSet][1] using the provided table name. | | [From(String, Type)][3] | Creates and returns a new [SqlSet][1] using the provided table name. | | [From<TResult>(String)][4] | Creates and returns a new [SqlSet<TResult>][5] using the provided table name. | Syntax ------ ```csharp public SqlSet From( string tableName ) ``` #### Parameters ##### *tableName*  [String][6] The name of the table that will be the source of data for the set. #### Return Value [SqlSet][1] A new [SqlSet][1] object. See Also -------- #### Reference [Database Class][7] [DbExtensions Namespace][2] [1]: ../SqlSet/README.md [2]: ../README.md [3]: From_1.md [4]: From__1.md [5]: ../SqlSet_1/README.md [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: README.md ================================================ FILE: docs/api/DbExtensions/Database/FromQuery.md ================================================ Database.FromQuery(SqlBuilder) Method ===================================== Creates and returns a new [SqlSet][1] using the provided defining query. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | | **FromQuery(SqlBuilder)** | Creates and returns a new [SqlSet][1] using the provided defining query. | | [FromQuery(SqlBuilder, Type)][3] | Creates and returns a new [SqlSet][1] using the provided defining query. | | [FromQuery<TResult>(SqlBuilder)][4] | Creates and returns a new [SqlSet<TResult>][5] using the provided defining query. | | [FromQuery<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][6] | Creates and returns a new [SqlSet<TResult>][5] using the provided defining query and mapper. | Syntax ------ ```csharp public SqlSet FromQuery( SqlBuilder definingQuery ) ``` #### Parameters ##### *definingQuery*  [SqlBuilder][7] The SQL query that will be the source of data for the set. #### Return Value [SqlSet][1] A new [SqlSet][1] object. See Also -------- #### Reference [Database Class][8] [DbExtensions Namespace][2] [1]: ../SqlSet/README.md [2]: ../README.md [3]: FromQuery_1.md [4]: FromQuery__1.md [5]: ../SqlSet_1/README.md [6]: FromQuery__1_1.md [7]: ../SqlBuilder/README.md [8]: README.md ================================================ FILE: docs/api/DbExtensions/Database/FromQuery_1.md ================================================ Database.FromQuery(SqlBuilder, Type) Method =========================================== Creates and returns a new [SqlSet][1] using the provided defining query. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | | [FromQuery(SqlBuilder)][3] | Creates and returns a new [SqlSet][1] using the provided defining query. | | **FromQuery(SqlBuilder, Type)** | Creates and returns a new [SqlSet][1] using the provided defining query. | | [FromQuery<TResult>(SqlBuilder)][4] | Creates and returns a new [SqlSet<TResult>][5] using the provided defining query. | | [FromQuery<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][6] | Creates and returns a new [SqlSet<TResult>][5] using the provided defining query and mapper. | Syntax ------ ```csharp public SqlSet FromQuery( SqlBuilder definingQuery, Type? resultType ) ``` #### Parameters ##### *definingQuery*  [SqlBuilder][7] The SQL query that will be the source of data for the set. ##### *resultType*  [Type][8] The type of objects to map the results to. #### Return Value [SqlSet][1] A new [SqlSet][1] object. See Also -------- #### Reference [Database Class][9] [DbExtensions Namespace][2] [1]: ../SqlSet/README.md [2]: ../README.md [3]: FromQuery.md [4]: FromQuery__1.md [5]: ../SqlSet_1/README.md [6]: FromQuery__1_1.md [7]: ../SqlBuilder/README.md [8]: https://learn.microsoft.com/dotnet/api/system.type [9]: README.md ================================================ FILE: docs/api/DbExtensions/Database/FromQuery__1.md ================================================ Database.FromQuery<TResult>(SqlBuilder) Method ================================================= Creates and returns a new [SqlSet<TResult>][1] using the provided defining query. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | | [FromQuery(SqlBuilder)][3] | Creates and returns a new [SqlSet][4] using the provided defining query. | | [FromQuery(SqlBuilder, Type)][5] | Creates and returns a new [SqlSet][4] using the provided defining query. | | **FromQuery<TResult>(SqlBuilder)** | Creates and returns a new [SqlSet<TResult>][1] using the provided defining query. | | [FromQuery<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][6] | Creates and returns a new [SqlSet<TResult>][1] using the provided defining query and mapper. | Syntax ------ ```csharp public SqlSet FromQuery( SqlBuilder definingQuery ) ``` #### Parameters ##### *definingQuery*  [SqlBuilder][7] The SQL query that will be the source of data for the set. #### Type Parameters ##### *TResult* The type of objects to map the results to. #### Return Value [SqlSet][1]<**TResult**> A new [SqlSet<TResult>][1] object. See Also -------- #### Reference [Database Class][8] [DbExtensions Namespace][2] [1]: ../SqlSet_1/README.md [2]: ../README.md [3]: FromQuery.md [4]: ../SqlSet/README.md [5]: FromQuery_1.md [6]: FromQuery__1_1.md [7]: ../SqlBuilder/README.md [8]: README.md ================================================ FILE: docs/api/DbExtensions/Database/FromQuery__1_1.md ================================================ Database.FromQuery<TResult>(SqlBuilder, Func<DbDataReader, TResult>) Method ================================================================================= Creates and returns a new [SqlSet<TResult>][1] using the provided defining query and mapper. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | | [FromQuery(SqlBuilder)][3] | Creates and returns a new [SqlSet][4] using the provided defining query. | | [FromQuery(SqlBuilder, Type)][5] | Creates and returns a new [SqlSet][4] using the provided defining query. | | [FromQuery<TResult>(SqlBuilder)][6] | Creates and returns a new [SqlSet<TResult>][1] using the provided defining query. | | **FromQuery<TResult>(SqlBuilder, Func<DbDataReader, TResult>)** | Creates and returns a new [SqlSet<TResult>][1] using the provided defining query and mapper. | Syntax ------ ```csharp public SqlSet FromQuery( SqlBuilder definingQuery, Func mapper ) ``` #### Parameters ##### *definingQuery*  [SqlBuilder][7] The SQL query that will be the source of data for the set. ##### *mapper*  [Func][8]<[DbDataReader][9], **TResult**> A custom mapper function that creates TResult instances from the rows in the set. #### Type Parameters ##### *TResult* The type of objects to map the results to. #### Return Value [SqlSet][1]<**TResult**> A new [SqlSet<TResult>][1] object. See Also -------- #### Reference [Database Class][10] [DbExtensions Namespace][2] [1]: ../SqlSet_1/README.md [2]: ../README.md [3]: FromQuery.md [4]: ../SqlSet/README.md [5]: FromQuery_1.md [6]: FromQuery__1.md [7]: ../SqlBuilder/README.md [8]: https://learn.microsoft.com/dotnet/api/system.func-2 [9]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [10]: README.md ================================================ FILE: docs/api/DbExtensions/Database/From_1.md ================================================ Database.From(String, Type) Method ================================== Creates and returns a new [SqlSet][1] using the provided table name. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------- | -------------------------------------------------------------------------------- | | [From(String)][3] | Creates and returns a new [SqlSet][1] using the provided table name. | | **From(String, Type)** | Creates and returns a new [SqlSet][1] using the provided table name. | | [From<TResult>(String)][4] | Creates and returns a new [SqlSet<TResult>][5] using the provided table name. | Syntax ------ ```csharp public SqlSet From( string tableName, Type? resultType ) ``` #### Parameters ##### *tableName*  [String][6] The name of the table that will be the source of data for the set. ##### *resultType*  [Type][7] The type of objects to map the results to. #### Return Value [SqlSet][1] A new [SqlSet][1] object. See Also -------- #### Reference [Database Class][8] [DbExtensions Namespace][2] [1]: ../SqlSet/README.md [2]: ../README.md [3]: From.md [4]: From__1.md [5]: ../SqlSet_1/README.md [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://learn.microsoft.com/dotnet/api/system.type [8]: README.md ================================================ FILE: docs/api/DbExtensions/Database/From__1.md ================================================ Database.From<TResult>(String) Method ======================================== Creates and returns a new [SqlSet<TResult>][1] using the provided table name. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------- | -------------------------------------------------------------------------------- | | [From(String)][3] | Creates and returns a new [SqlSet][4] using the provided table name. | | [From(String, Type)][5] | Creates and returns a new [SqlSet][4] using the provided table name. | | **From<TResult>(String)** | Creates and returns a new [SqlSet<TResult>][1] using the provided table name. | Syntax ------ ```csharp public SqlSet From( string tableName ) ``` #### Parameters ##### *tableName*  [String][6] The name of the table that will be the source of data for the set. #### Type Parameters ##### *TResult* The type of objects to map the results to. #### Return Value [SqlSet][1]<**TResult**> A new [SqlSet<TResult>][1] object. See Also -------- #### Reference [Database Class][7] [DbExtensions Namespace][2] [1]: ../SqlSet_1/README.md [2]: ../README.md [3]: From.md [4]: ../SqlSet/README.md [5]: From_1.md [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: README.md ================================================ FILE: docs/api/DbExtensions/Database/LastInsertId.md ================================================ Database.LastInsertId Method ============================ Gets the identity value of the last inserted record. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public virtual Object? LastInsertId() ``` #### Return Value [Object][2] The identity value of the last inserted record. Remarks ------- It is very important to keep the connection open between the last command and this one, or else you might get the wrong value. See Also -------- #### Reference [Database Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: README.md ================================================ FILE: docs/api/DbExtensions/Database/LastInsertIdAsync.md ================================================ Database.LastInsertIdAsync Method ================================= Gets the identity value of the last inserted record. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public virtual ValueTask LastInsertIdAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][2]  (Optional) The [CancellationToken][2] to monitor for cancellation requests. The default is [None][3]. #### Return Value [ValueTask][4]<[Object][5]> The identity value of the last inserted record. Remarks ------- It is very important to keep the connection open between the last command and this one, or else you might get the wrong value. See Also -------- #### Reference [Database Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [4]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [5]: https://learn.microsoft.com/dotnet/api/system.object [6]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Map.md ================================================ Database.Map(SqlBuilder) Method =============================== Maps the results of the *query* to dynamic objects. The query is deferred-executed. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | **Map(SqlBuilder)** | Maps the results of the *query* to dynamic objects. The query is deferred-executed. | | [Map(SqlBuilder, Type)][2] | Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. | | [Map<TResult>(SqlBuilder)][3] | Maps the results of the *query* to TResult objects. The query is deferred-executed. | | [Map<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][4] | Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. | Syntax ------ ```csharp public IEnumerable Map( SqlBuilder query ) ``` #### Parameters ##### *query*  [SqlBuilder][5] The query. #### Return Value [IEnumerable][6]<[Object][7]> The results of the query as dynamic objects. See Also -------- #### Reference [Database Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: Map_1.md [3]: Map__1.md [4]: Map__1_1.md [5]: ../SqlBuilder/README.md [6]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [7]: https://learn.microsoft.com/dotnet/api/system.object [8]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Map_1.md ================================================ Database.Map(SqlBuilder, Type) Method ===================================== Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | [Map(SqlBuilder)][2] | Maps the results of the *query* to dynamic objects. The query is deferred-executed. | | **Map(SqlBuilder, Type)** | Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. | | [Map<TResult>(SqlBuilder)][3] | Maps the results of the *query* to TResult objects. The query is deferred-executed. | | [Map<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][4] | Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. | Syntax ------ ```csharp public IEnumerable Map( SqlBuilder query, Type resultType ) ``` #### Parameters ##### *query*  [SqlBuilder][5] The query. ##### *resultType*  [Type][6] The type of objects to map the results to. #### Return Value [IEnumerable][7]<[Object][8]> The results of the query as objects of type specified by the *resultType* parameter. See Also -------- #### Reference [Database Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: Map.md [3]: Map__1.md [4]: Map__1_1.md [5]: ../SqlBuilder/README.md [6]: https://learn.microsoft.com/dotnet/api/system.type [7]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [8]: https://learn.microsoft.com/dotnet/api/system.object [9]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Map__1.md ================================================ Database.Map<TResult>(SqlBuilder) Method =========================================== Maps the results of the *query* to TResult objects. The query is deferred-executed. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | [Map(SqlBuilder)][2] | Maps the results of the *query* to dynamic objects. The query is deferred-executed. | | [Map(SqlBuilder, Type)][3] | Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. | | **Map<TResult>(SqlBuilder)** | Maps the results of the *query* to TResult objects. The query is deferred-executed. | | [Map<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][4] | Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. | Syntax ------ ```csharp public IEnumerable Map( SqlBuilder query ) ``` #### Parameters ##### *query*  [SqlBuilder][5] The query. #### Type Parameters ##### *TResult* The type of objects to map the results to. #### Return Value [IEnumerable][6]<**TResult**> The results of the query as TResult objects. See Also -------- #### Reference [Database Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: Map.md [3]: Map_1.md [4]: Map__1_1.md [5]: ../SqlBuilder/README.md [6]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [7]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Map__1_1.md ================================================ Database.Map<TResult>(SqlBuilder, Func<DbDataReader, TResult>) Method =========================================================================== Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | [Map(SqlBuilder)][2] | Maps the results of the *query* to dynamic objects. The query is deferred-executed. | | [Map(SqlBuilder, Type)][3] | Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. | | [Map<TResult>(SqlBuilder)][4] | Maps the results of the *query* to TResult objects. The query is deferred-executed. | | **Map<TResult>(SqlBuilder, Func<DbDataReader, TResult>)** | Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. | Syntax ------ ```csharp public IEnumerable Map( SqlBuilder query, Func mapper ) ``` #### Parameters ##### *query*  [SqlBuilder][5] The query. ##### *mapper*  [Func][6]<[DbDataReader][7], **TResult**> The delegate for creating TResult objects from an [DbDataReader][7] object. #### Type Parameters ##### *TResult* The type of objects to map the results to. #### Return Value [IEnumerable][8]<**TResult**> The results of the query as TResult objects. See Also -------- #### Reference [Database Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: Map.md [3]: Map_1.md [4]: Map__1.md [5]: ../SqlBuilder/README.md [6]: https://learn.microsoft.com/dotnet/api/system.func-2 [7]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [8]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [9]: README.md ================================================ FILE: docs/api/DbExtensions/Database/QuoteIdentifier.md ================================================ Database.QuoteIdentifier Method =============================== Given an unquoted identifier in the correct catalog case, returns the correct quoted form of that identifier. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string QuoteIdentifier( string identifier ) ``` #### Parameters ##### *identifier*  [String][2] The original identifier. #### Return Value [String][2] The quoted version of the identifier. If the indentifier is already quoted it's returned unchanged. See Also -------- #### Reference [Database Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/Database/README.md ================================================ Database Class ============== Provides simple data access using [SqlSet][1], [SqlBuilder][2] and [SqlTable<TEntity>][3]. Inheritance Hierarchy --------------------- [System.Object][4]   **DbExtensions.Database** **Namespace:** [DbExtensions][5] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public class Database : IDisposable ``` The **Database** type exposes the following members. Constructors ------------ | Name | Description | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | [Database(DbConnection)][6] | Initializes a new instance of the **Database** class using the provided connection. | | [Database(String, String)][7] | Initializes a new instance of the **Database** class using the provided connection string and provider's invariant name. | Properties ---------- | Name | Description | | ------------------ | ----------------------------------------------------------- | | [Configuration][8] | Provides access to configuration options for this instance. | | [Connection][9] | Gets the connection to associate with new commands. | | [Transaction][10] | Gets or sets a transaction to associate with new commands. | Methods ------- | Name | Description | | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | [Add][11] | Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. | | [AddAsync][12] | Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. | | [AsyncMap(SqlBuilder)][13] | Maps the results of the *query* to dynamic objects. The query is deferred-executed. | | [AsyncMap(SqlBuilder, Type)][14] | Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. | | [AsyncMap<TResult>(SqlBuilder)][15] | Maps the results of the *query* to TResult objects. The query is deferred-executed. | | [AsyncMap<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][16] | Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. | | [CreateCommand][17] | Creates and returns a [DbCommand][18] object from the specified *sqlBuilder*. | | [Dispose()][19] | Releases all resources used by the current instance of the **Database** class. | | [Dispose(Boolean)][20] | Releases the resources used by this **Database** instance. | | [EnsureConnectionOpen][21] | Opens [Connection][9] (if it's not open) and returns an [IDisposable][22] object you can use to close it (if it wasn't open). | | [EnsureConnectionOpenAsync][23] | Opens [Connection][9] (if it's not open) and returns an [IAsyncDisposable][24] object you can use to close it (if it wasn't open). | | [EnsureInTransaction()][25] | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | | [EnsureInTransaction(IsolationLevel)][26] | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | | [EnsureInTransactionAsync(CancellationToken)][27] | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | | [EnsureInTransactionAsync(IsolationLevel, CancellationToken)][28] | Returns a virtual transaction that you can use to ensure a code block is always executed in a transaction, new or existing. | | [Execute][29] | Executes the *nonQuery* command. Optionally uses a transaction and validates affected records value before committing. | | [ExecuteAsync][30] | Executes the *nonQuery* command. Optionally uses a transaction and validates affected records value before committing. | | [Find<TEntity>][31] | Gets the entity whose primary key matches the *id* parameter. | | [FindAsync<TEntity>][32] | Gets the entity whose primary key matches the *id* parameter. | | [From(String)][33] | Creates and returns a new [SqlSet][1] using the provided table name. | | [From(String, Type)][34] | Creates and returns a new [SqlSet][1] using the provided table name. | | [From<TResult>(String)][35] | Creates and returns a new [SqlSet<TResult>][36] using the provided table name. | | [FromQuery(SqlBuilder)][37] | Creates and returns a new [SqlSet][1] using the provided defining query. | | [FromQuery(SqlBuilder, Type)][38] | Creates and returns a new [SqlSet][1] using the provided defining query. | | [FromQuery<TResult>(SqlBuilder)][39] | Creates and returns a new [SqlSet<TResult>][36] using the provided defining query. | | [FromQuery<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][40] | Creates and returns a new [SqlSet<TResult>][36] using the provided defining query and mapper. | | [LastInsertId][41] | Gets the identity value of the last inserted record. | | [LastInsertIdAsync][42] | Gets the identity value of the last inserted record. | | [Map(SqlBuilder)][43] | Maps the results of the *query* to dynamic objects. The query is deferred-executed. | | [Map(SqlBuilder, Type)][44] | Maps the results of the *query* to objects of type specified by the *resultType* parameter. The query is deferred-executed. | | [Map<TResult>(SqlBuilder)][45] | Maps the results of the *query* to TResult objects. The query is deferred-executed. | | [Map<TResult>(SqlBuilder, Func<DbDataReader, TResult>)][46] | Maps the results of the *query* to TResult objects, using the provided *mapper* delegate. | | [QuoteIdentifier][47] | Given an unquoted identifier in the correct catalog case, returns the correct quoted form of that identifier. | | [Remove][48] | Executes a DELETE command for the specified *entity*. | | [RemoveAsync][49] | Executes a DELETE command for the specified *entity*. | | [Table(Type)][50] | Returns the [SqlTable][51] instance for the specified *entityType*. | | [Table<TEntity>()][52] | Returns the [SqlTable<TEntity>][3] instance for the specified TEntity. | | [Update(Object)][53] | Executes an UPDATE command for the specified *entity*. | | [Update(Object, Object)][54] | Executes an UPDATE command for the specified *entity*. | | [UpdateAsync(Object, CancellationToken)][55] | Executes an UPDATE command for the specified *entity*. | | [UpdateAsync(Object, Object, CancellationToken)][56] | Executes an UPDATE command for the specified *entity*. | See Also -------- #### Reference [DbExtensions Namespace][5] [1]: ../SqlSet/README.md [2]: ../SqlBuilder/README.md [3]: ../SqlTable_1/README.md [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: ../README.md [6]: _ctor.md [7]: _ctor_1.md [8]: Configuration.md [9]: Connection.md [10]: Transaction.md [11]: Add.md [12]: AddAsync.md [13]: AsyncMap.md [14]: AsyncMap_1.md [15]: AsyncMap__1.md [16]: AsyncMap__1_1.md [17]: CreateCommand.md [18]: https://learn.microsoft.com/dotnet/api/system.data.common.dbcommand [19]: Dispose.md [20]: Dispose_1.md [21]: EnsureConnectionOpen.md [22]: https://learn.microsoft.com/dotnet/api/system.idisposable [23]: EnsureConnectionOpenAsync.md [24]: https://learn.microsoft.com/dotnet/api/system.iasyncdisposable [25]: EnsureInTransaction.md [26]: EnsureInTransaction_1.md [27]: EnsureInTransactionAsync_1.md [28]: EnsureInTransactionAsync.md [29]: Execute.md [30]: ExecuteAsync.md [31]: Find__1.md [32]: FindAsync__1.md [33]: From.md [34]: From_1.md [35]: From__1.md [36]: ../SqlSet_1/README.md [37]: FromQuery.md [38]: FromQuery_1.md [39]: FromQuery__1.md [40]: FromQuery__1_1.md [41]: LastInsertId.md [42]: LastInsertIdAsync.md [43]: Map.md [44]: Map_1.md [45]: Map__1.md [46]: Map__1_1.md [47]: QuoteIdentifier.md [48]: Remove.md [49]: RemoveAsync.md [50]: Table.md [51]: ../SqlTable/README.md [52]: Table__1.md [53]: Update.md [54]: Update_1.md [55]: UpdateAsync_1.md [56]: UpdateAsync.md ================================================ FILE: docs/api/DbExtensions/Database/Remove.md ================================================ Database.Remove Method ====================== Executes a DELETE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool Remove( Object entity ) ``` #### Parameters ##### *entity*  [Object][2] The entity whose DELETE command is to be executed. #### Return Value [Boolean][3] `true` if *entity* is deleted; otherwise, `false`. Remarks ------- This method is a shortcut for `db.Table(entity.GetType()).Remove(entity)`. See Also -------- #### Reference [Database Class][4] [DbExtensions Namespace][1] [SqlTable.Remove(Object)][5] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.boolean [4]: README.md [5]: ../SqlTable/Remove.md ================================================ FILE: docs/api/DbExtensions/Database/RemoveAsync.md ================================================ Database.RemoveAsync Method =========================== Executes a DELETE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask RemoveAsync( Object entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [Object][2] The entity whose DELETE command is to be executed. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[Boolean][6]> `true` if *entity* is deleted; otherwise, `false`. Remarks ------- This method is a shortcut for `await db.Table(entity.GetType()).RemoveAsync(entity, cancellationToken)`. See Also -------- #### Reference [Database Class][7] [DbExtensions Namespace][1] [SqlTable.RemoveAsync(Object, CancellationToken)][8] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.boolean [7]: README.md [8]: ../SqlTable/RemoveAsync.md ================================================ FILE: docs/api/DbExtensions/Database/Table.md ================================================ Database.Table(Type) Method =========================== Returns the [SqlTable][1] instance for the specified *entityType*. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------ | ------------------------------------------------------------------------- | | **Table(Type)** | Returns the [SqlTable][1] instance for the specified *entityType*. | | [Table<TEntity>()][3] | Returns the [SqlTable<TEntity>][4] instance for the specified TEntity. | Syntax ------ ```csharp public SqlTable Table( Type entityType ) ``` #### Parameters ##### *entityType*  [Type][5] The type of the entity. #### Return Value [SqlTable][1] The [SqlTable][1] instance for *entityType*. See Also -------- #### Reference [Database Class][6] [DbExtensions Namespace][2] [1]: ../SqlTable/README.md [2]: ../README.md [3]: Table__1.md [4]: ../SqlTable_1/README.md [5]: https://learn.microsoft.com/dotnet/api/system.type [6]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Table__1.md ================================================ Database.Table<TEntity> Method ================================= Returns the [SqlTable<TEntity>][1] instance for the specified TEntity. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------- | ------------------------------------------------------------------------- | | [Table(Type)][3] | Returns the [SqlTable][4] instance for the specified *entityType*. | | **Table<TEntity>()** | Returns the [SqlTable<TEntity>][1] instance for the specified TEntity. | Syntax ------ ```csharp public SqlTable Table() where TEntity : class ``` #### Type Parameters ##### *TEntity* The type of the entity. #### Return Value [SqlTable][1]<**TEntity**> The [SqlTable<TEntity>][1] instance for TEntity. See Also -------- #### Reference [Database Class][5] [DbExtensions Namespace][2] [1]: ../SqlTable_1/README.md [2]: ../README.md [3]: Table.md [4]: ../SqlTable/README.md [5]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Transaction.md ================================================ Database.Transaction Property ============================= Gets or sets a transaction to associate with new commands. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public DbTransaction? Transaction { get; set; } ``` #### Property Value [DbTransaction][2] See Also -------- #### Reference [Database Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.data.common.dbtransaction [3]: README.md ================================================ FILE: docs/api/DbExtensions/Database/Update.md ================================================ Database.Update(Object) Method ============================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------- | ------------------------------------------------------ | | **Update(Object)** | Executes an UPDATE command for the specified *entity*. | | [Update(Object, Object)][2] | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public void Update( Object entity ) ``` #### Parameters ##### *entity*  [Object][3] The entity whose UPDATE command is to be executed. Remarks ------- This method is a shortcut for `db.Table(entity.GetType()).Update(entity)`. See Also -------- #### Reference [Database Class][4] [DbExtensions Namespace][1] [SqlTable.Update(Object)][5] [1]: ../README.md [2]: Update_1.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md [5]: ../SqlTable/Update.md ================================================ FILE: docs/api/DbExtensions/Database/UpdateAsync.md ================================================ Database.UpdateAsync(Object, Object, CancellationToken) Method ============================================================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------- | ------------------------------------------------------ | | [UpdateAsync(Object, CancellationToken)][2] | Executes an UPDATE command for the specified *entity*. | | **UpdateAsync(Object, Object, CancellationToken)** | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public ValueTask UpdateAsync( Object entity, Object? originalId, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [Object][3] The entity whose UPDATE command is to be executed. ##### *originalId*  [Object][3] The original primary key value. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6] Remarks ------- This method is a shortcut for `await db.Table(entity.GetType()).UpdateAsync(entity, originalId, cancellationToken)`. See Also -------- #### Reference [Database Class][7] [DbExtensions Namespace][1] [SqlTable.UpdateAsync(Object, Object, CancellationToken)][8] [1]: ../README.md [2]: UpdateAsync_1.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [7]: README.md [8]: ../SqlTable/UpdateAsync.md ================================================ FILE: docs/api/DbExtensions/Database/UpdateAsync_1.md ================================================ Database.UpdateAsync(Object, CancellationToken) Method ====================================================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------- | ------------------------------------------------------ | | **UpdateAsync(Object, CancellationToken)** | Executes an UPDATE command for the specified *entity*. | | [UpdateAsync(Object, Object, CancellationToken)][2] | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public ValueTask UpdateAsync( Object entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [Object][3] The entity whose UPDATE command is to be executed. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6] Remarks ------- This method is a shortcut for `await db.Table(entity.GetType()).UpdateAsync(entity, cancellationToken)`. See Also -------- #### Reference [Database Class][7] [DbExtensions Namespace][1] [SqlTable.UpdateAsync(Object, CancellationToken)][8] [1]: ../README.md [2]: UpdateAsync.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [7]: README.md [8]: ../SqlTable/UpdateAsync_1.md ================================================ FILE: docs/api/DbExtensions/Database/Update_1.md ================================================ Database.Update(Object, Object) Method ====================================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------- | ------------------------------------------------------ | | [Update(Object)][2] | Executes an UPDATE command for the specified *entity*. | | **Update(Object, Object)** | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public void Update( Object entity, Object? originalId ) ``` #### Parameters ##### *entity*  [Object][3] The entity whose UPDATE command is to be executed. ##### *originalId*  [Object][3] The original primary key value. Remarks ------- This method is a shortcut for `db.Table(entity.GetType()).Update(entity, originalId)`. See Also -------- #### Reference [Database Class][4] [DbExtensions Namespace][1] [SqlTable.Update(Object, Object)][5] [1]: ../README.md [2]: Update.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md [5]: ../SqlTable/Update_1.md ================================================ FILE: docs/api/DbExtensions/Database/_ctor.md ================================================ Database(DbConnection) Constructor ================================== Initializes a new instance of the [Database][1] class using the provided connection. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | **Database(DbConnection)** | Initializes a new instance of the [Database][1] class using the provided connection. | | [Database(String, String)][3] | Initializes a new instance of the [Database][1] class using the provided connection string and provider's invariant name. | Syntax ------ ```csharp public Database( DbConnection connection ) ``` #### Parameters ##### *connection*  [DbConnection][4] The connection. See Also -------- #### Reference [Database Class][1] [DbExtensions Namespace][2] [1]: README.md [2]: ../README.md [3]: _ctor_1.md [4]: https://learn.microsoft.com/dotnet/api/system.data.common.dbconnection ================================================ FILE: docs/api/DbExtensions/Database/_ctor_1.md ================================================ Database(String, String) Constructor ==================================== Initializes a new instance of the [Database][1] class using the provided connection string and provider's invariant name. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | [Database(DbConnection)][3] | Initializes a new instance of the [Database][1] class using the provided connection. | | **Database(String, String)** | Initializes a new instance of the [Database][1] class using the provided connection string and provider's invariant name. | Syntax ------ ```csharp public Database( string connectionString, string providerInvariantName ) ``` #### Parameters ##### *connectionString*  [String][4] The connection string. ##### *providerInvariantName*  [String][4] The provider's invariant name. See Also -------- #### Reference [Database Class][1] [DbExtensions Namespace][2] [1]: README.md [2]: ../README.md [3]: _ctor.md [4]: https://learn.microsoft.com/dotnet/api/system.string ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/CommandTimeout.md ================================================ DatabaseConfiguration.CommandTimeout Property ============================================= Specifies a timeout to assign to commands. This setting is ignored if less or equal to -1. The default is -1. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public int CommandTimeout { get; set; } ``` #### Property Value [Int32][2] See Also -------- #### Reference [DatabaseConfiguration Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.int32 [3]: README.md ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/DefaultComplexPropertySeparator.md ================================================ DatabaseConfiguration.DefaultComplexPropertySeparator Property ============================================================== The default separator to use when mapping complex properties. The default value is null, which means no separator is used, unless an explicit separator is specified on [ComplexPropertyAttribute.Separator][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string? DefaultComplexPropertySeparator { get; set; } ``` #### Property Value [String][3] See Also -------- #### Reference [DatabaseConfiguration Class][4] [DbExtensions Namespace][2] [1]: ../ComplexPropertyAttribute/Separator.md [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/EnableBatchCommands.md ================================================ DatabaseConfiguration.EnableBatchCommands Property ================================================== `true` to execute batch commands when possible; otherwise, `false`. The default is `true`. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool EnableBatchCommands { get; set; } ``` #### Property Value [Boolean][2] Remarks ------- This setting affects the behavior of [AddRange(TEntity[])][3], [UpdateRange(TEntity[])][4] and [RemoveRange(TEntity[])][5]. See Also -------- #### Reference [DatabaseConfiguration Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.boolean [3]: ../SqlTable_1/AddRange_1.md [4]: ../SqlTable_1/UpdateRange_1.md [5]: ../SqlTable_1/RemoveRange_1.md [6]: README.md ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/LastInsertIdCommand.md ================================================ DatabaseConfiguration.LastInsertIdCommand Property ================================================== Gets or sets the SQL command that returns the last identity value generated on the database. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string LastInsertIdCommand { get; set; } ``` #### Property Value [String][2] See Also -------- #### Reference [DatabaseConfiguration Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/Log.md ================================================ DatabaseConfiguration.Log Property ================================== Specifies the destination to write the SQL query or command. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public TextWriter? Log { get; set; } ``` #### Property Value [TextWriter][2] See Also -------- #### Reference [DatabaseConfiguration Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.io.textwriter [3]: README.md ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/ParameterNameBuilder.md ================================================ DatabaseConfiguration.ParameterNameBuilder Property =================================================== Specifies a function that prepares a parameter name to be used on [DbParameter.ParameterName][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public Func ParameterNameBuilder { get; set; } ``` #### Property Value [Func][3]<[String][4], [String][4]> See Also -------- #### Reference [DatabaseConfiguration Class][5] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.data.common.dbparameter.parametername [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.func-2 [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: README.md ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/ParameterPlaceholderBuilder.md ================================================ DatabaseConfiguration.ParameterPlaceholderBuilder Property ========================================================== Specifies a function that builds a parameter placeholder to be used in SQL statements. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public Func ParameterPlaceholderBuilder { get; set; } ``` #### Property Value [Func][2]<[String][3], [String][3]> See Also -------- #### Reference [DatabaseConfiguration Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.func-2 [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/QuotePrefix.md ================================================ DatabaseConfiguration.QuotePrefix Property ========================================== Gets or sets the beginning character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string QuotePrefix { get; set; } ``` #### Property Value [String][2] See Also -------- #### Reference [DatabaseConfiguration Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/QuoteSuffix.md ================================================ DatabaseConfiguration.QuoteSuffix Property ========================================== Gets or sets the ending character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string QuoteSuffix { get; set; } ``` #### Property Value [String][2] See Also -------- #### Reference [DatabaseConfiguration Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/README.md ================================================ DatabaseConfiguration Class =========================== Holds configuration options that customize the behavior of [Database][1]. This class cannot be instantiated, to get an instance use the [Configuration][2] property. Inheritance Hierarchy --------------------- [System.Object][3]   **DbExtensions.DatabaseConfiguration** **Namespace:** [DbExtensions][4] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public sealed class DatabaseConfiguration ``` The **DatabaseConfiguration** type exposes the following members. Properties ---------- | Name | Description | | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [CommandTimeout][5] | Specifies a timeout to assign to commands. This setting is ignored if less or equal to -1. The default is -1. | | [DefaultComplexPropertySeparator][6] | The default separator to use when mapping complex properties. The default value is null, which means no separator is used, unless an explicit separator is specified on [ComplexPropertyAttribute.Separator][7]. | | [EnableBatchCommands][8] | `true` to execute batch commands when possible; otherwise, `false`. The default is `true`. | | [LastInsertIdCommand][9] | Gets or sets the SQL command that returns the last identity value generated on the database. | | [Log][10] | Specifies the destination to write the SQL query or command. | | [ParameterNameBuilder][11] | Specifies a function that prepares a parameter name to be used on [DbParameter.ParameterName][12]. | | [ParameterPlaceholderBuilder][13] | Specifies a function that builds a parameter placeholder to be used in SQL statements. | | [QuotePrefix][14] | Gets or sets the beginning character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. | | [QuoteSuffix][15] | Gets or sets the ending character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. | | [UseVersionMember][16] | `true` to include version column check in SQL statements' predicates; otherwise, `false`. The default is `true`. | See Also -------- #### Reference [DbExtensions Namespace][4] [1]: ../Database/README.md [2]: ../Database/Configuration.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: ../README.md [5]: CommandTimeout.md [6]: DefaultComplexPropertySeparator.md [7]: ../ComplexPropertyAttribute/Separator.md [8]: EnableBatchCommands.md [9]: LastInsertIdCommand.md [10]: Log.md [11]: ParameterNameBuilder.md [12]: https://learn.microsoft.com/dotnet/api/system.data.common.dbparameter.parametername [13]: ParameterPlaceholderBuilder.md [14]: QuotePrefix.md [15]: QuoteSuffix.md [16]: UseVersionMember.md ================================================ FILE: docs/api/DbExtensions/DatabaseConfiguration/UseVersionMember.md ================================================ DatabaseConfiguration.UseVersionMember Property =============================================== `true` to include version column check in SQL statements' predicates; otherwise, `false`. The default is `true`. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool UseVersionMember { get; set; } ``` #### Property Value [Boolean][2] See Also -------- #### Reference [DatabaseConfiguration Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.boolean [3]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetBoolean.md ================================================ Extensions.GetBoolean Method ============================ Gets the value of the specified column as a [Boolean][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static bool GetBoolean( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][4] The name of the column to find. #### Return Value [Boolean][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.boolean [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetByte.md ================================================ Extensions.GetByte Method ========================= Gets the value of the specified column as a [Byte][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static byte GetByte( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][4] The name of the column to find. #### Return Value [Byte][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.byte [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetChar.md ================================================ Extensions.GetChar Method ========================= Gets the value of the specified column as a [Char][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static char GetChar( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][4] The name of the column to find. #### Return Value [Char][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.char [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetDateTime.md ================================================ Extensions.GetDateTime Method ============================= Gets the value of the specified column as a [DateTime][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static DateTime GetDateTime( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][4] The name of the column to find. #### Return Value [DateTime][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.datetime [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetDecimal.md ================================================ Extensions.GetDecimal Method ============================ Gets the value of the specified column as a [Decimal][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static decimal GetDecimal( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][4] The name of the column to find. #### Return Value [Decimal][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.decimal [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetDouble.md ================================================ Extensions.GetDouble Method =========================== Gets the value of the specified column as a [Double][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static double GetDouble( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][4] The name of the column to find. #### Return Value [Double][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.double [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetFloat.md ================================================ Extensions.GetFloat Method ========================== Gets the value of the specified column as a [Single][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static float GetFloat( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][4] The name of the column to find. #### Return Value [Single][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.single [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetInt16.md ================================================ Extensions.GetInt16 Method ========================== Gets the value of the specified column as an [Int16][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static short GetInt16( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][4] The name of the column to find. #### Return Value [Int16][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.int16 [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetInt32.md ================================================ Extensions.GetInt32 Method ========================== Gets the value of the specified column as an [Int32][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static int GetInt32( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][4] The name of the column to find. #### Return Value [Int32][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.int32 [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetInt64.md ================================================ Extensions.GetInt64 Method ========================== Gets the value of the specified column as an [Int64][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static long GetInt64( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][4] The name of the column to find. #### Return Value [Int64][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.int64 [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableBoolean.md ================================================ Extensions.GetNullableBoolean(DbDataReader, Int32) Method ========================================================= Gets the value of the specified column as a [Nullable<T>][1] of [Boolean][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------- | -------------------------------------------------------------------------------- | | **GetNullableBoolean(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [Boolean][2]. | | [GetNullableBoolean(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Boolean][2]. | Syntax ------ ```csharp public static bool? GetNullableBoolean( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][6] The zero-based column ordinal. #### Return Value [Nullable][1]<[Boolean][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.boolean [3]: ../README.md [4]: GetNullableBoolean_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.int32 [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableBoolean_1.md ================================================ Extensions.GetNullableBoolean(DbDataReader, String) Method ========================================================== Gets the value of the specified column as a [Nullable<T>][1] of [Boolean][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------- | -------------------------------------------------------------------------------- | | [GetNullableBoolean(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Boolean][2]. | | **GetNullableBoolean(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [Boolean][2]. | Syntax ------ ```csharp public static bool? GetNullableBoolean( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[Boolean][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.boolean [3]: ../README.md [4]: GetNullableBoolean.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableByte.md ================================================ Extensions.GetNullableByte(DbDataReader, Int32) Method ====================================================== Gets the value of the specified column as a [Nullable<T>][1] of [Byte][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | ----------------------------------------------------------------------------- | | **GetNullableByte(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [Byte][2]. | | [GetNullableByte(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Byte][2]. | Syntax ------ ```csharp public static byte? GetNullableByte( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][6] The zero-based column ordinal. #### Return Value [Nullable][1]<[Byte][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.byte [3]: ../README.md [4]: GetNullableByte_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.int32 [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableByte_1.md ================================================ Extensions.GetNullableByte(DbDataReader, String) Method ======================================================= Gets the value of the specified column as a [Nullable<T>][1] of [Byte][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------- | ----------------------------------------------------------------------------- | | [GetNullableByte(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Byte][2]. | | **GetNullableByte(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [Byte][2]. | Syntax ------ ```csharp public static byte? GetNullableByte( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[Byte][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.byte [3]: ../README.md [4]: GetNullableByte.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableChar.md ================================================ Extensions.GetNullableChar(DbDataReader, Int32) Method ====================================================== Gets the value of the specified column as a [Nullable<T>][1] of [Char][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | ----------------------------------------------------------------------------- | | **GetNullableChar(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [Char][2]. | | [GetNullableChar(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Char][2]. | Syntax ------ ```csharp public static char? GetNullableChar( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][6] The zero-based column ordinal. #### Return Value [Nullable][1]<[Char][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.char [3]: ../README.md [4]: GetNullableChar_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.int32 [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableChar_1.md ================================================ Extensions.GetNullableChar(DbDataReader, String) Method ======================================================= Gets the value of the specified column as a [Nullable<T>][1] of [Char][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------- | ----------------------------------------------------------------------------- | | [GetNullableChar(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Char][2]. | | **GetNullableChar(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [Char][2]. | Syntax ------ ```csharp public static char? GetNullableChar( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[Char][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.char [3]: ../README.md [4]: GetNullableChar.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableDateTime.md ================================================ Extensions.GetNullableDateTime(DbDataReader, Int32) Method ========================================================== Gets the value of the specified column as a [Nullable<T>][1] of [DateTime][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------- | --------------------------------------------------------------------------------- | | **GetNullableDateTime(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [DateTime][2]. | | [GetNullableDateTime(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [DateTime][2]. | Syntax ------ ```csharp public static DateTime? GetNullableDateTime( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][6] The zero-based column ordinal. #### Return Value [Nullable][1]<[DateTime][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.datetime [3]: ../README.md [4]: GetNullableDateTime_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.int32 [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableDateTime_1.md ================================================ Extensions.GetNullableDateTime(DbDataReader, String) Method =========================================================== Gets the value of the specified column as a [Nullable<T>][1] of [DateTime][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------- | --------------------------------------------------------------------------------- | | [GetNullableDateTime(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [DateTime][2]. | | **GetNullableDateTime(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [DateTime][2]. | Syntax ------ ```csharp public static DateTime? GetNullableDateTime( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[DateTime][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.datetime [3]: ../README.md [4]: GetNullableDateTime.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableDecimal.md ================================================ Extensions.GetNullableDecimal(DbDataReader, Int32) Method ========================================================= Gets the value of the specified column as a [Nullable<T>][1] of [Decimal][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------- | -------------------------------------------------------------------------------- | | **GetNullableDecimal(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [Decimal][2]. | | [GetNullableDecimal(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Decimal][2]. | Syntax ------ ```csharp public static decimal? GetNullableDecimal( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][6] The zero-based column ordinal. #### Return Value [Nullable][1]<[Decimal][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.decimal [3]: ../README.md [4]: GetNullableDecimal_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.int32 [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableDecimal_1.md ================================================ Extensions.GetNullableDecimal(DbDataReader, String) Method ========================================================== Gets the value of the specified column as a [Nullable<T>][1] of [Decimal][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------- | -------------------------------------------------------------------------------- | | [GetNullableDecimal(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Decimal][2]. | | **GetNullableDecimal(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [Decimal][2]. | Syntax ------ ```csharp public static decimal? GetNullableDecimal( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[Decimal][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.decimal [3]: ../README.md [4]: GetNullableDecimal.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableDouble.md ================================================ Extensions.GetNullableDouble(DbDataReader, Int32) Method ======================================================== Gets the value of the specified column as a [Nullable<T>][1] of [Double][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------- | ------------------------------------------------------------------------------- | | **GetNullableDouble(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [Double][2]. | | [GetNullableDouble(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Double][2]. | Syntax ------ ```csharp public static double? GetNullableDouble( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][6] The zero-based column ordinal. #### Return Value [Nullable][1]<[Double][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.double [3]: ../README.md [4]: GetNullableDouble_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.int32 [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableDouble_1.md ================================================ Extensions.GetNullableDouble(DbDataReader, String) Method ========================================================= Gets the value of the specified column as a [Nullable<T>][1] of [Double][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------- | ------------------------------------------------------------------------------- | | [GetNullableDouble(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Double][2]. | | **GetNullableDouble(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [Double][2]. | Syntax ------ ```csharp public static double? GetNullableDouble( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[Double][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.double [3]: ../README.md [4]: GetNullableDouble.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableFloat.md ================================================ Extensions.GetNullableFloat(DbDataReader, Int32) Method ======================================================= Gets the value of the specified column as a [Nullable<T>][1] of [Single][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------- | ------------------------------------------------------------------------------- | | **GetNullableFloat(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [Single][2]. | | [GetNullableFloat(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Single][2]. | Syntax ------ ```csharp public static float? GetNullableFloat( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][6] The zero-based column ordinal. #### Return Value [Nullable][1]<[Single][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.single [3]: ../README.md [4]: GetNullableFloat_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.int32 [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableFloat_1.md ================================================ Extensions.GetNullableFloat(DbDataReader, String) Method ======================================================== Gets the value of the specified column as a [Nullable<T>][1] of [Single][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | ------------------------------------------------------------------------------- | | [GetNullableFloat(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Single][2]. | | **GetNullableFloat(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [Single][2]. | Syntax ------ ```csharp public static float? GetNullableFloat( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[Single][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.single [3]: ../README.md [4]: GetNullableFloat.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableGuid.md ================================================ Extensions.GetNullableGuid(DbDataReader, Int32) Method ====================================================== Gets the value of the specified column as a [Nullable<T>][1] of [Guid][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | ----------------------------------------------------------------------------- | | **GetNullableGuid(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [Guid][2]. | | [GetNullableGuid(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Guid][2]. | Syntax ------ ```csharp public static Guid? GetNullableGuid( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][6] The zero-based column ordinal. #### Return Value [Nullable][1]<[Guid][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.guid [3]: ../README.md [4]: GetNullableGuid_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.int32 [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableGuid_1.md ================================================ Extensions.GetNullableGuid(DbDataReader, String) Method ======================================================= Gets the value of the specified column as a [Nullable<T>][1] of [Guid][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------- | ----------------------------------------------------------------------------- | | [GetNullableGuid(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Guid][2]. | | **GetNullableGuid(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [Guid][2]. | Syntax ------ ```csharp public static Guid? GetNullableGuid( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[Guid][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.guid [3]: ../README.md [4]: GetNullableGuid.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableInt16.md ================================================ Extensions.GetNullableInt16(DbDataReader, Int32) Method ======================================================= Gets the value of the specified column as a [Nullable<T>][1] of [Int16][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------- | ------------------------------------------------------------------------------ | | **GetNullableInt16(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [Int16][2]. | | [GetNullableInt16(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Int16][2]. | Syntax ------ ```csharp public static short? GetNullableInt16( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][6] The zero-based column ordinal. #### Return Value [Nullable][1]<[Int16][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.int16 [3]: ../README.md [4]: GetNullableInt16_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.int32 [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableInt16_1.md ================================================ Extensions.GetNullableInt16(DbDataReader, String) Method ======================================================== Gets the value of the specified column as a [Nullable<T>][1] of [Int16][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | ------------------------------------------------------------------------------ | | [GetNullableInt16(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Int16][2]. | | **GetNullableInt16(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [Int16][2]. | Syntax ------ ```csharp public static short? GetNullableInt16( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[Int16][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.int16 [3]: ../README.md [4]: GetNullableInt16.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableInt32.md ================================================ Extensions.GetNullableInt32(DbDataReader, Int32) Method ======================================================= Gets the value of the specified column as a [Nullable<T>][1] of [Int32][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------- | ------------------------------------------------------------------------------ | | **GetNullableInt32(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [Int32][2]. | | [GetNullableInt32(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Int32][2]. | Syntax ------ ```csharp public static int? GetNullableInt32( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][2] The zero-based column ordinal. #### Return Value [Nullable][1]<[Int32][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][6] or [Extension Methods (C# Programming Guide)][7]. See Also -------- #### Reference [Extensions Class][8] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.int32 [3]: ../README.md [4]: GetNullableInt32_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [7]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [8]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableInt32_1.md ================================================ Extensions.GetNullableInt32(DbDataReader, String) Method ======================================================== Gets the value of the specified column as a [Nullable<T>][1] of [Int32][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | ------------------------------------------------------------------------------ | | [GetNullableInt32(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Int32][2]. | | **GetNullableInt32(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [Int32][2]. | Syntax ------ ```csharp public static int? GetNullableInt32( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[Int32][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.int32 [3]: ../README.md [4]: GetNullableInt32.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableInt64.md ================================================ Extensions.GetNullableInt64(DbDataReader, Int32) Method ======================================================= Gets the value of the specified column as a [Nullable<T>][1] of [Int64][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------- | ------------------------------------------------------------------------------ | | **GetNullableInt64(DbDataReader, Int32)** | Gets the value of the specified column as a [Nullable<T>][1] of [Int64][2]. | | [GetNullableInt64(DbDataReader, String)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Int64][2]. | Syntax ------ ```csharp public static long? GetNullableInt64( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *i*  [Int32][6] The zero-based column ordinal. #### Return Value [Nullable][1]<[Int64][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.int64 [3]: ../README.md [4]: GetNullableInt64_1.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.int32 [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetNullableInt64_1.md ================================================ Extensions.GetNullableInt64(DbDataReader, String) Method ======================================================== Gets the value of the specified column as a [Nullable<T>][1] of [Int64][2]. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | ------------------------------------------------------------------------------ | | [GetNullableInt64(DbDataReader, Int32)][4] | Gets the value of the specified column as a [Nullable<T>][1] of [Int64][2]. | | **GetNullableInt64(DbDataReader, String)** | Gets the value of the specified column as a [Nullable<T>][1] of [Int64][2]. | Syntax ------ ```csharp public static long? GetNullableInt64( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][5] The data reader. ##### *name*  [String][6] The name of the column to find. #### Return Value [Nullable][1]<[Int64][2]> The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][5]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][7] or [Extension Methods (C# Programming Guide)][8]. See Also -------- #### Reference [Extensions Class][9] [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [2]: https://learn.microsoft.com/dotnet/api/system.int64 [3]: ../README.md [4]: GetNullableInt64.md [5]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [8]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [9]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetString.md ================================================ Extensions.GetString Method =========================== Gets the value of the specified column as a [String][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static string GetString( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][3] The data reader. ##### *name*  [String][1] The name of the column to find. #### Return Value [String][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][3]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][4] or [Extension Methods (C# Programming Guide)][5]. See Also -------- #### Reference [Extensions Class][6] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.string [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [4]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [5]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [6]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetStringOrNull.md ================================================ Extensions.GetStringOrNull(DbDataReader, Int32) Method ====================================================== Gets the value of the specified column as a [String][1], or null (Nothing in Visual Basic). **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | ------------------------------------------------------------------------------------------- | | **GetStringOrNull(DbDataReader, Int32)** | Gets the value of the specified column as a [String][1], or null (Nothing in Visual Basic). | | [GetStringOrNull(DbDataReader, String)][3] | Gets the value of the specified column as a [String][1], or null (Nothing in Visual Basic). | Syntax ------ ```csharp public static string? GetStringOrNull( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][4] The data reader. ##### *i*  [Int32][5] The zero-based column ordinal. #### Return Value [String][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][4]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][6] or [Extension Methods (C# Programming Guide)][7]. See Also -------- #### Reference [Extensions Class][8] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.string [2]: ../README.md [3]: GetStringOrNull_1.md [4]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [5]: https://learn.microsoft.com/dotnet/api/system.int32 [6]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [7]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [8]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetStringOrNull_1.md ================================================ Extensions.GetStringOrNull(DbDataReader, String) Method ======================================================= Gets the value of the specified column as a [String][1], or null (Nothing in Visual Basic). **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------- | ------------------------------------------------------------------------------------------- | | [GetStringOrNull(DbDataReader, Int32)][3] | Gets the value of the specified column as a [String][1], or null (Nothing in Visual Basic). | | **GetStringOrNull(DbDataReader, String)** | Gets the value of the specified column as a [String][1], or null (Nothing in Visual Basic). | Syntax ------ ```csharp public static string? GetStringOrNull( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][4] The data reader. ##### *name*  [String][1] The name of the column to find. #### Return Value [String][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][4]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.string [2]: ../README.md [3]: GetStringOrNull.md [4]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetValue.md ================================================ Extensions.GetValue Method ========================== Gets the value of the specified column. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static Object GetValue( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][2] The data reader. ##### *name*  [String][3] The name of the column to find. #### Return Value [Object][4] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][2]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][5] or [Extension Methods (C# Programming Guide)][6]. See Also -------- #### Reference [Extensions Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [6]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [7]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetValueOrNull.md ================================================ Extensions.GetValueOrNull(DbDataReader, Int32) Method ===================================================== Gets the value of the specified column as an [Object][1], or null (Nothing in Visual Basic). **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------- | -------------------------------------------------------------------------------------------- | | **GetValueOrNull(DbDataReader, Int32)** | Gets the value of the specified column as an [Object][1], or null (Nothing in Visual Basic). | | [GetValueOrNull(DbDataReader, String)][3] | Gets the value of the specified column as an [Object][1], or null (Nothing in Visual Basic). | Syntax ------ ```csharp public static Object? GetValueOrNull( this DbDataReader reader, int i ) ``` #### Parameters ##### *reader*  [DbDataReader][4] The data reader. ##### *i*  [Int32][5] The zero-based column ordinal. #### Return Value [Object][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][4]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][6] or [Extension Methods (C# Programming Guide)][7]. See Also -------- #### Reference [Extensions Class][8] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.object [2]: ../README.md [3]: GetValueOrNull_1.md [4]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [5]: https://learn.microsoft.com/dotnet/api/system.int32 [6]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [7]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [8]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/GetValueOrNull_1.md ================================================ Extensions.GetValueOrNull(DbDataReader, String) Method ====================================================== Gets the value of the specified column as an [Object][1], or null (Nothing in Visual Basic). **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------- | -------------------------------------------------------------------------------------------- | | [GetValueOrNull(DbDataReader, Int32)][3] | Gets the value of the specified column as an [Object][1], or null (Nothing in Visual Basic). | | **GetValueOrNull(DbDataReader, String)** | Gets the value of the specified column as an [Object][1], or null (Nothing in Visual Basic). | Syntax ------ ```csharp public static Object? GetValueOrNull( this DbDataReader reader, string name ) ``` #### Parameters ##### *reader*  [DbDataReader][4] The data reader. ##### *name*  [String][5] The name of the column to find. #### Return Value [Object][1] The value of the column. #### Usage Note In Visual Basic and C#, you can call this method as an instance method on any object of type [DbDataReader][4]. When you use instance method syntax to call this method, omit the first parameter. For more information, see [Extension Methods (Visual Basic)][6] or [Extension Methods (C# Programming Guide)][7]. See Also -------- #### Reference [Extensions Class][8] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.object [2]: ../README.md [3]: GetValueOrNull.md [4]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [5]: https://learn.microsoft.com/dotnet/api/system.string [6]: https://docs.microsoft.com/dotnet/visual-basic/programming-guide/language-features/procedures/extension-methods [7]: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods [8]: README.md ================================================ FILE: docs/api/DbExtensions/Extensions/README.md ================================================ Extensions Class ================ Provides extension methods for common ADO.NET objects. Inheritance Hierarchy --------------------- [System.Object][1]   **DbExtensions.Extensions** **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static class Extensions ``` The **Extensions** type exposes the following members. Methods ------- | Name | Description | | ----------------------------------------------- | -------------------------------------------------------------------------------------------- | | [GetBoolean][3] | Gets the value of the specified column as a [Boolean][4]. | | [GetByte][5] | Gets the value of the specified column as a [Byte][6]. | | [GetChar][7] | Gets the value of the specified column as a [Char][8]. | | [GetDateTime][9] | Gets the value of the specified column as a [DateTime][10]. | | [GetDecimal][11] | Gets the value of the specified column as a [Decimal][12]. | | [GetDouble][13] | Gets the value of the specified column as a [Double][14]. | | [GetFloat][15] | Gets the value of the specified column as a [Single][16]. | | [GetInt16][17] | Gets the value of the specified column as an [Int16][18]. | | [GetInt32][19] | Gets the value of the specified column as an [Int32][20]. | | [GetInt64][21] | Gets the value of the specified column as an [Int64][22]. | | [GetNullableBoolean(DbDataReader, Int32)][23] | Gets the value of the specified column as a [Nullable<T>][24] of [Boolean][4]. | | [GetNullableBoolean(DbDataReader, String)][25] | Gets the value of the specified column as a [Nullable<T>][24] of [Boolean][4]. | | [GetNullableByte(DbDataReader, Int32)][26] | Gets the value of the specified column as a [Nullable<T>][24] of [Byte][6]. | | [GetNullableByte(DbDataReader, String)][27] | Gets the value of the specified column as a [Nullable<T>][24] of [Byte][6]. | | [GetNullableChar(DbDataReader, Int32)][28] | Gets the value of the specified column as a [Nullable<T>][24] of [Char][8]. | | [GetNullableChar(DbDataReader, String)][29] | Gets the value of the specified column as a [Nullable<T>][24] of [Char][8]. | | [GetNullableDateTime(DbDataReader, Int32)][30] | Gets the value of the specified column as a [Nullable<T>][24] of [DateTime][10]. | | [GetNullableDateTime(DbDataReader, String)][31] | Gets the value of the specified column as a [Nullable<T>][24] of [DateTime][10]. | | [GetNullableDecimal(DbDataReader, Int32)][32] | Gets the value of the specified column as a [Nullable<T>][24] of [Decimal][12]. | | [GetNullableDecimal(DbDataReader, String)][33] | Gets the value of the specified column as a [Nullable<T>][24] of [Decimal][12]. | | [GetNullableDouble(DbDataReader, Int32)][34] | Gets the value of the specified column as a [Nullable<T>][24] of [Double][14]. | | [GetNullableDouble(DbDataReader, String)][35] | Gets the value of the specified column as a [Nullable<T>][24] of [Double][14]. | | [GetNullableFloat(DbDataReader, Int32)][36] | Gets the value of the specified column as a [Nullable<T>][24] of [Single][16]. | | [GetNullableFloat(DbDataReader, String)][37] | Gets the value of the specified column as a [Nullable<T>][24] of [Single][16]. | | [GetNullableGuid(DbDataReader, Int32)][38] | Gets the value of the specified column as a [Nullable<T>][24] of [Guid][39]. | | [GetNullableGuid(DbDataReader, String)][40] | Gets the value of the specified column as a [Nullable<T>][24] of [Guid][39]. | | [GetNullableInt16(DbDataReader, Int32)][41] | Gets the value of the specified column as a [Nullable<T>][24] of [Int16][18]. | | [GetNullableInt16(DbDataReader, String)][42] | Gets the value of the specified column as a [Nullable<T>][24] of [Int16][18]. | | [GetNullableInt32(DbDataReader, Int32)][43] | Gets the value of the specified column as a [Nullable<T>][24] of [Int32][20]. | | [GetNullableInt32(DbDataReader, String)][44] | Gets the value of the specified column as a [Nullable<T>][24] of [Int32][20]. | | [GetNullableInt64(DbDataReader, Int32)][45] | Gets the value of the specified column as a [Nullable<T>][24] of [Int64][22]. | | [GetNullableInt64(DbDataReader, String)][46] | Gets the value of the specified column as a [Nullable<T>][24] of [Int64][22]. | | [GetString][47] | Gets the value of the specified column as a [String][48]. | | [GetStringOrNull(DbDataReader, Int32)][49] | Gets the value of the specified column as a [String][48], or null (Nothing in Visual Basic). | | [GetStringOrNull(DbDataReader, String)][50] | Gets the value of the specified column as a [String][48], or null (Nothing in Visual Basic). | | [GetValue][51] | Gets the value of the specified column. | | [GetValueOrNull(DbDataReader, Int32)][52] | Gets the value of the specified column as an [Object][1], or null (Nothing in Visual Basic). | | [GetValueOrNull(DbDataReader, String)][53] | Gets the value of the specified column as an [Object][1], or null (Nothing in Visual Basic). | See Also -------- #### Reference [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.object [2]: ../README.md [3]: GetBoolean.md [4]: https://learn.microsoft.com/dotnet/api/system.boolean [5]: GetByte.md [6]: https://learn.microsoft.com/dotnet/api/system.byte [7]: GetChar.md [8]: https://learn.microsoft.com/dotnet/api/system.char [9]: GetDateTime.md [10]: https://learn.microsoft.com/dotnet/api/system.datetime [11]: GetDecimal.md [12]: https://learn.microsoft.com/dotnet/api/system.decimal [13]: GetDouble.md [14]: https://learn.microsoft.com/dotnet/api/system.double [15]: GetFloat.md [16]: https://learn.microsoft.com/dotnet/api/system.single [17]: GetInt16.md [18]: https://learn.microsoft.com/dotnet/api/system.int16 [19]: GetInt32.md [20]: https://learn.microsoft.com/dotnet/api/system.int32 [21]: GetInt64.md [22]: https://learn.microsoft.com/dotnet/api/system.int64 [23]: GetNullableBoolean.md [24]: https://learn.microsoft.com/dotnet/api/system.nullable-1 [25]: GetNullableBoolean_1.md [26]: GetNullableByte.md [27]: GetNullableByte_1.md [28]: GetNullableChar.md [29]: GetNullableChar_1.md [30]: GetNullableDateTime.md [31]: GetNullableDateTime_1.md [32]: GetNullableDecimal.md [33]: GetNullableDecimal_1.md [34]: GetNullableDouble.md [35]: GetNullableDouble_1.md [36]: GetNullableFloat.md [37]: GetNullableFloat_1.md [38]: GetNullableGuid.md [39]: https://learn.microsoft.com/dotnet/api/system.guid [40]: GetNullableGuid_1.md [41]: GetNullableInt16.md [42]: GetNullableInt16_1.md [43]: GetNullableInt32.md [44]: GetNullableInt32_1.md [45]: GetNullableInt64.md [46]: GetNullableInt64_1.md [47]: GetString.md [48]: https://learn.microsoft.com/dotnet/api/system.string [49]: GetStringOrNull.md [50]: GetStringOrNull_1.md [51]: GetValue.md [52]: GetValueOrNull.md [53]: GetValueOrNull_1.md ================================================ FILE: docs/api/DbExtensions/README.md ================================================ DbExtensions Namespace ====================== DbExtensions is a data-access framework with a strong focus on query composition, granularity and code aesthetics. [Database][1] is the entry point of the **DbExtensions** API. Classes ------- | Class | Description | | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [AssociationAttribute][2] | Designates a property to represent a database association, such as a foreign key relationship. | | [ChangeConflictException][3] | An exception that is thrown when a concurrency violation is encountered while saving to the database. A concurrency violation occurs when an unexpected number of rows are affected during save. This is usually because the data in the database has been modified since it was loaded into memory. | | [ColumnAttribute][4] | Associates a property with a column in a database table. | | [ComplexPropertyAttribute][5] | Designates a property as a complex property that groups columns of a table that share the same base name. | | [Database][1] | Provides simple data access using [SqlSet][6], [SqlBuilder][7] and [SqlTable<TEntity>][8]. | | [DatabaseConfiguration][9] | Holds configuration options that customize the behavior of [Database][1]. This class cannot be instantiated, to get an instance use the [Configuration][10] property. | | [Extensions][11] | Provides extension methods for common ADO.NET objects. | | [SQL][12] | Provides a set of static (Shared in Visual Basic) methods to create [SqlBuilder][7] instances. | | [SqlBuilder][7] | Represents a mutable SQL string. | | [SqlClause][13] | Provides information about a SQL clause. Used by [SqlBuilder][7]. | | [SqlSet][6] | Represents an immutable, connected SQL query. This class cannot be instantiated, to get an instance use one of the [Database.From][14] or [Database.FromQuery][15] overloads. | | [SqlSet<TResult>][16] | Represents an immutable, connected SQL query that maps to TResult objects. This class cannot be instantiated, to get an instance use one of the [Database.From<TResult>(String)][17] or [Database.FromQuery<TResult>(SqlBuilder)][18] overloads. | | [SqlTable][19] | A non-generic version of [SqlTable<TEntity>][8] which can be used when the type of the entity is not known at build time. This class cannot be instantiated, to get an instance use the [Database.Table(Type)][20] method. | | [SqlTable<TEntity>][8] | A [SqlSet<TResult>][16] that provides CRUD (Create, Read, Update, Delete) operations for annotated classes. This class cannot be instantiated, to get an instance use the [Database.Table<TEntity>()][21] method. | | [TableAttribute][22] | Designates a class as an entity class that is associated with a database table. | Enumerations ------------ | Enumeration | Description | | -------------- | ----------------------------------------------------------------------------------------------------------------------------- | | [AutoSync][23] | Used to specify for during INSERT and UPDATE operations when a data member should be read back after the operation completes. | [1]: Database/README.md [2]: AssociationAttribute/README.md [3]: ChangeConflictException/README.md [4]: ColumnAttribute/README.md [5]: ComplexPropertyAttribute/README.md [6]: SqlSet/README.md [7]: SqlBuilder/README.md [8]: SqlTable_1/README.md [9]: DatabaseConfiguration/README.md [10]: Database/Configuration.md [11]: Extensions/README.md [12]: SQL/README.md [13]: SqlClause/README.md [14]: Database/From.md [15]: Database/FromQuery.md [16]: SqlSet_1/README.md [17]: Database/From__1.md [18]: Database/FromQuery__1.md [19]: SqlTable/README.md [20]: Database/Table.md [21]: Database/Table__1.md [22]: TableAttribute/README.md [23]: AutoSync/README.md ================================================ FILE: docs/api/DbExtensions/SQL/DELETE_FROM.md ================================================ SQL.DELETE_FROM(SqlBuilder.ClauseStringHandler<SqlClause.DELETE_FROM>) Method ================================================================================ Creates and returns a new [SqlBuilder][1] initialized by appending the DELETE FROM clause using the provided string interpolated *handler*. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | **DELETE_FROM(SqlBuilder.ClauseStringHandler<DELETE_FROM>)** | Creates and returns a new [SqlBuilder][1] initialized by appending the DELETE FROM clause using the provided string interpolated *handler*. | | [DELETE_FROM(String)][3] | Creates and returns a new [SqlBuilder][1] initialized by appending the DELETE FROM clause using the provided *text*. | Syntax ------ ```csharp public static SqlBuilder DELETE_FROM( ref ClauseStringHandler handler ) ``` #### Parameters ##### *handler*  ClauseStringHandler<DELETE_FROM> The body of the DELETE FROM clause. #### Return Value [SqlBuilder][1] A new [SqlBuilder][1] after calling [DELETE_FROM(SqlBuilder.ClauseStringHandler<DELETE_FROM>)][4]. See Also -------- #### Reference [SQL Class][5] [DbExtensions Namespace][2] [1]: ../SqlBuilder/README.md [2]: ../README.md [3]: DELETE_FROM_1.md [4]: ../SqlBuilder/DELETE_FROM.md [5]: README.md ================================================ FILE: docs/api/DbExtensions/SQL/DELETE_FROM_1.md ================================================ SQL.DELETE_FROM(String) Method ============================== Creates and returns a new [SqlBuilder][1] initialized by appending the DELETE FROM clause using the provided *text*. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | [DELETE_FROM(SqlBuilder.ClauseStringHandler<DELETE_FROM>)][3] | Creates and returns a new [SqlBuilder][1] initialized by appending the DELETE FROM clause using the provided string interpolated *handler*. | | **DELETE_FROM(String)** | Creates and returns a new [SqlBuilder][1] initialized by appending the DELETE FROM clause using the provided *text*. | Syntax ------ ```csharp public static SqlBuilder DELETE_FROM( string? text ) ``` #### Parameters ##### *text*  [String][4] The body of the DELETE FROM clause. #### Return Value [SqlBuilder][1] A new [SqlBuilder][1] after calling [DELETE_FROM(String)][5]. See Also -------- #### Reference [SQL Class][6] [DbExtensions Namespace][2] [1]: ../SqlBuilder/README.md [2]: ../README.md [3]: DELETE_FROM.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: ../SqlBuilder/DELETE_FROM_1.md [6]: README.md ================================================ FILE: docs/api/DbExtensions/SQL/INSERT_INTO.md ================================================ SQL.INSERT_INTO(SqlBuilder.ClauseStringHandler<SqlClause.INSERT_INTO>) Method ================================================================================ Creates and returns a new [SqlBuilder][1] initialized by appending the INSERT INTO clause using the provided string interpolated *handler*. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | **INSERT_INTO(SqlBuilder.ClauseStringHandler<INSERT_INTO>)** | Creates and returns a new [SqlBuilder][1] initialized by appending the INSERT INTO clause using the provided string interpolated *handler*. | | [INSERT_INTO(String)][3] | Creates and returns a new [SqlBuilder][1] initialized by appending the INSERT INTO clause using the provided *text*. | Syntax ------ ```csharp public static SqlBuilder INSERT_INTO( ref ClauseStringHandler handler ) ``` #### Parameters ##### *handler*  ClauseStringHandler<INSERT_INTO> The body of the INSERT INTO clause. #### Return Value [SqlBuilder][1] A new [SqlBuilder][1] after calling [INSERT_INTO(SqlBuilder.ClauseStringHandler<INSERT_INTO>)][4]. See Also -------- #### Reference [SQL Class][5] [DbExtensions Namespace][2] [1]: ../SqlBuilder/README.md [2]: ../README.md [3]: INSERT_INTO_1.md [4]: ../SqlBuilder/INSERT_INTO.md [5]: README.md ================================================ FILE: docs/api/DbExtensions/SQL/INSERT_INTO_1.md ================================================ SQL.INSERT_INTO(String) Method ============================== Creates and returns a new [SqlBuilder][1] initialized by appending the INSERT INTO clause using the provided *text*. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | [INSERT_INTO(SqlBuilder.ClauseStringHandler<INSERT_INTO>)][3] | Creates and returns a new [SqlBuilder][1] initialized by appending the INSERT INTO clause using the provided string interpolated *handler*. | | **INSERT_INTO(String)** | Creates and returns a new [SqlBuilder][1] initialized by appending the INSERT INTO clause using the provided *text*. | Syntax ------ ```csharp public static SqlBuilder INSERT_INTO( string? text ) ``` #### Parameters ##### *text*  [String][4] The body of the INSERT INTO clause. #### Return Value [SqlBuilder][1] A new [SqlBuilder][1] after calling [INSERT_INTO(String)][5]. See Also -------- #### Reference [SQL Class][6] [DbExtensions Namespace][2] [1]: ../SqlBuilder/README.md [2]: ../README.md [3]: INSERT_INTO.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: ../SqlBuilder/INSERT_INTO_1.md [6]: README.md ================================================ FILE: docs/api/DbExtensions/SQL/README.md ================================================ SQL Class ========= Provides a set of static (Shared in Visual Basic) methods to create [SqlBuilder][1] instances. Inheritance Hierarchy --------------------- [System.Object][2]   **DbExtensions.SQL** **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static class SQL ``` The **SQL** type exposes the following members. Methods ------- | Name | Description | | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | [DELETE_FROM(SqlBuilder.ClauseStringHandler<DELETE_FROM>)][4] | Creates and returns a new [SqlBuilder][1] initialized by appending the DELETE FROM clause using the provided string interpolated *handler*. | | [DELETE_FROM(String)][5] | Creates and returns a new [SqlBuilder][1] initialized by appending the DELETE FROM clause using the provided *text*. | | [INSERT_INTO(SqlBuilder.ClauseStringHandler<INSERT_INTO>)][6] | Creates and returns a new [SqlBuilder][1] initialized by appending the INSERT INTO clause using the provided string interpolated *handler*. | | [INSERT_INTO(String)][7] | Creates and returns a new [SqlBuilder][1] initialized by appending the INSERT INTO clause using the provided *text*. | | [SELECT(SqlBuilder.ClauseStringHandler<SELECT>)][8] | Creates and returns a new [SqlBuilder][1] initialized by appending the SELECT clause using the provided string interpolated *handler*. | | [SELECT(String)][9] | Creates and returns a new [SqlBuilder][1] initialized by appending the SELECT clause using the provided *text*. | | [UPDATE(SqlBuilder.ClauseStringHandler<UPDATE>)][10] | Creates and returns a new [SqlBuilder][1] initialized by appending the UPDATE clause using the provided string interpolated *handler*. | | [UPDATE(String)][11] | Creates and returns a new [SqlBuilder][1] initialized by appending the UPDATE clause using the provided *text*. | | [WITH(SqlBuilder.ClauseStringHandler<WITH>)][12] | Creates and returns a new [SqlBuilder][1] initialized by appending the WITH clause using the provided string interpolated *handler*. | | [WITH(String)][13] | Creates and returns a new [SqlBuilder][1] initialized by appending the WITH clause using the provided *text*. | | [WITH(String, SqlBuilder)][14] | Creates and returns a new [SqlBuilder][1] initialized by appending the WITH clause using the provided *subQuery* and *alias*. | | [WITH(String, SqlSet)][15] | Creates and returns a new [SqlBuilder][1] initialized by appending the WITH clause using the provided *subQuery* and *alias*. | See Also -------- #### Reference [DbExtensions Namespace][3] [1]: ../SqlBuilder/README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: ../README.md [4]: DELETE_FROM.md [5]: DELETE_FROM_1.md [6]: INSERT_INTO.md [7]: INSERT_INTO_1.md [8]: SELECT.md [9]: SELECT_1.md [10]: UPDATE.md [11]: UPDATE_1.md [12]: WITH.md [13]: WITH_1.md [14]: WITH_2.md [15]: WITH_3.md ================================================ FILE: docs/api/DbExtensions/SQL/SELECT.md ================================================ SQL.SELECT(SqlBuilder.ClauseStringHandler<SqlClause.SELECT>) Method ====================================================================== Creates and returns a new [SqlBuilder][1] initialized by appending the SELECT clause using the provided string interpolated *handler*. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | **SELECT(SqlBuilder.ClauseStringHandler<SELECT>)** | Creates and returns a new [SqlBuilder][1] initialized by appending the SELECT clause using the provided string interpolated *handler*. | | [SELECT(String)][3] | Creates and returns a new [SqlBuilder][1] initialized by appending the SELECT clause using the provided *text*. | Syntax ------ ```csharp public static SqlBuilder SELECT( ref ClauseStringHandler handler ) ``` #### Parameters ##### *handler*  ClauseStringHandler<SELECT> The interpolated string that represents the body of the SELECT clause. #### Return Value [SqlBuilder][5] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: SELECT.md [3]: _If.md [4]: SELECT_2.md [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/SELECT_2.md ================================================ SqlBuilder.SELECT(String) Method ================================ Appends the SELECT clause using the provided *text*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | | [SELECT()][2] | Sets SELECT as the next clause, to be used by subsequent calls to clause continuation methods, such as [_If(Boolean, ConditionalStringHandler)][3]. | | [SELECT(SqlBuilder.ClauseStringHandler<SELECT>)][4] | Appends the SELECT clause using the provided interpolated string *handler*. | | **SELECT(String)** | Appends the SELECT clause using the provided *text*. | Syntax ------ ```csharp public SqlBuilder SELECT( string? text ) ``` #### Parameters ##### *text*  [String][5] The text that represents the body of the SELECT clause. #### Return Value [SqlBuilder][6] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: SELECT.md [3]: _If.md [4]: SELECT_1.md [5]: https://learn.microsoft.com/dotnet/api/system.string [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/SET.md ================================================ SqlBuilder.SET(SqlBuilder.ClauseStringHandler<SqlClause.SET>) Method ======================================================================= Appends the SET clause using the provided interpolated string *handler*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------------- | ------------------------------------------------------------------------ | | **SET(SqlBuilder.ClauseStringHandler<SET>)** | Appends the SET clause using the provided interpolated string *handler*. | | [SET(String)][2] | Appends the SET clause using the provided *text*. | Syntax ------ ```csharp public SqlBuilder SET( ref ClauseStringHandler handler ) ``` #### Parameters ##### *handler*  ClauseStringHandler<SET> The interpolated string that represents the body of the SET clause. #### Return Value [SqlBuilder][3] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: SET_1.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/SET_1.md ================================================ SqlBuilder.SET(String) Method ============================= Appends the SET clause using the provided *text*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------ | ------------------------------------------------------------------------ | | [SET(SqlBuilder.ClauseStringHandler<SET>)][2] | Appends the SET clause using the provided interpolated string *handler*. | | **SET(String)** | Appends the SET clause using the provided *text*. | Syntax ------ ```csharp public SqlBuilder SET( string? text ) ``` #### Parameters ##### *text*  [String][3] The text that represents the body of the SET clause. #### Return Value [SqlBuilder][4] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: SET.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/SetCurrentClause.md ================================================ SqlBuilder.SetCurrentClause(SqlClause) Method ============================================= Sets *clause* as the current SQL clause. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------- | ---------------------------------------------------------------- | | **SetCurrentClause(SqlClause)** | Sets *clause* as the current SQL clause. | | [SetCurrentClause<TClause>()][2] | Sets the clause identified by TClause as the current SQL clause. | Syntax ------ ```csharp public SqlBuilder SetCurrentClause( SqlClause? clause ) ``` #### Parameters ##### *clause*  [SqlClause][3] The SQL clause. #### Return Value [SqlBuilder][4] A reference to this instance after the operation has completed. See Also -------- #### Reference [SqlBuilder Class][4] [DbExtensions Namespace][1] [CurrentClause][5] [1]: ../README.md [2]: SetCurrentClause__1.md [3]: ../SqlClause/README.md [4]: README.md [5]: CurrentClause.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/SetCurrentClause__1.md ================================================ SqlBuilder.SetCurrentClause<TClause> Method ============================================== Sets the clause identified by TClause as the current SQL clause. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------- | ---------------------------------------------------------------- | | [SetCurrentClause(SqlClause)][2] | Sets *clause* as the current SQL clause. | | **SetCurrentClause<TClause>()** | Sets the clause identified by TClause as the current SQL clause. | Syntax ------ ```csharp public SqlBuilder SetCurrentClause() where TClause : new(), SqlClause ``` #### Type Parameters ##### *TClause* The type of the SQL clause. #### Return Value [SqlBuilder][3] A reference to this instance after the operation has completed. See Also -------- #### Reference [SqlBuilder Class][3] [DbExtensions Namespace][1] [CurrentClause][4] [1]: ../README.md [2]: SetCurrentClause.md [3]: README.md [4]: CurrentClause.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/SetNextClause.md ================================================ SqlBuilder.SetNextClause(SqlClause) Method ========================================== Sets *clause* as the next SQL clause. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------- | ------------------------------------------------------------- | | **SetNextClause(SqlClause)** | Sets *clause* as the next SQL clause. | | [SetNextClause<TClause>()][2] | Sets the clause identified by TClause as the next SQL clause. | Syntax ------ ```csharp public SqlBuilder SetNextClause( SqlClause? clause ) ``` #### Parameters ##### *clause*  [SqlClause][3] The SQL clause. #### Return Value [SqlBuilder][4] A reference to this instance after the operation has completed. See Also -------- #### Reference [SqlBuilder Class][4] [DbExtensions Namespace][1] [NextClause][5] [1]: ../README.md [2]: SetNextClause__1.md [3]: ../SqlClause/README.md [4]: README.md [5]: NextClause.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/SetNextClause__1.md ================================================ SqlBuilder.SetNextClause<TClause> Method =========================================== Sets the clause identified by TClause as the next SQL clause. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------- | ------------------------------------------------------------- | | [SetNextClause(SqlClause)][2] | Sets *clause* as the next SQL clause. | | **SetNextClause<TClause>()** | Sets the clause identified by TClause as the next SQL clause. | Syntax ------ ```csharp public SqlBuilder SetNextClause() where TClause : new(), SqlClause ``` #### Type Parameters ##### *TClause* The type of the SQL clause. #### Return Value [SqlBuilder][3] A reference to this instance after the operation has completed. See Also -------- #### Reference [SqlBuilder Class][3] [DbExtensions Namespace][1] [NextClause][4] [1]: ../README.md [2]: SetNextClause.md [3]: README.md [4]: NextClause.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/ToString.md ================================================ SqlBuilder.ToString Method ========================== Converts the value of this instance to a [String][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public override string ToString() ``` #### Return Value [String][1] A string whose value is the same as this instance. See Also -------- #### Reference [SqlBuilder Class][3] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.string [2]: ../README.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/UNION.md ================================================ SqlBuilder.UNION Method ======================= Appends the UNION clause. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlBuilder UNION() ``` #### Return Value [SqlBuilder][2] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][2] [DbExtensions Namespace][1] [1]: ../README.md [2]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/UPDATE.md ================================================ SqlBuilder.UPDATE(SqlBuilder.ClauseStringHandler<SqlClause.UPDATE>) Method ============================================================================= Appends the UPDATE clause using the provided interpolated string *handler*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------------------- | --------------------------------------------------------------------------- | | **UPDATE(SqlBuilder.ClauseStringHandler<UPDATE>)** | Appends the UPDATE clause using the provided interpolated string *handler*. | | [UPDATE(String)][2] | Appends the UPDATE clause using the provided *text*. | Syntax ------ ```csharp public SqlBuilder UPDATE( ref ClauseStringHandler handler ) ``` #### Parameters ##### *handler*  ClauseStringHandler<UPDATE> The interpolated string that represents the body of the UPDATE clause. #### Return Value [SqlBuilder][3] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: UPDATE_1.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/UPDATE_1.md ================================================ SqlBuilder.UPDATE(String) Method ================================ Appends the UPDATE clause using the provided *text*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------ | --------------------------------------------------------------------------- | | [UPDATE(SqlBuilder.ClauseStringHandler<UPDATE>)][2] | Appends the UPDATE clause using the provided interpolated string *handler*. | | **UPDATE(String)** | Appends the UPDATE clause using the provided *text*. | Syntax ------ ```csharp public SqlBuilder UPDATE( string? text ) ``` #### Parameters ##### *text*  [String][3] The text that represents the body of the UPDATE clause. #### Return Value [SqlBuilder][4] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: UPDATE.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/VALUES.md ================================================ SqlBuilder.VALUES(SqlBuilder.ClauseStringHandler<SqlClause.VALUES>) Method ============================================================================= Appends the VALUES clause using the provided interpolated string *handler*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------------------- | --------------------------------------------------------------------------- | | **VALUES(SqlBuilder.ClauseStringHandler<VALUES>)** | Appends the VALUES clause using the provided interpolated string *handler*. | | [VALUES(Object[])][2] | Appends the VALUES clause using the provided parameters. | Syntax ------ ```csharp public SqlBuilder VALUES( ref ClauseStringHandler handler ) ``` #### Parameters ##### *handler*  ClauseStringHandler<VALUES> The interpolated string that represents the body of the VALUES clause. #### Return Value [SqlBuilder][3] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: VALUES_1.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/VALUES_1.md ================================================ SqlBuilder.VALUES(Object[]) Method ================================== Appends the VALUES clause using the provided parameters. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------ | --------------------------------------------------------------------------- | | [VALUES(SqlBuilder.ClauseStringHandler<VALUES>)][2] | Appends the VALUES clause using the provided interpolated string *handler*. | | **VALUES(Object[])** | Appends the VALUES clause using the provided parameters. | Syntax ------ ```csharp public SqlBuilder VALUES( params Object?[] args ) ``` #### Parameters ##### *args*  [Object][3][] The parameters of the clause body. #### Return Value [SqlBuilder][4] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: VALUES.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/WHERE.md ================================================ SqlBuilder.WHERE Method ======================= Sets WHERE as the next clause, to be used by subsequent calls to clause continuation methods, such as [_If(Boolean, ConditionalStringHandler)][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | **WHERE()** | Sets WHERE as the next clause, to be used by subsequent calls to clause continuation methods, such as [_If(Boolean, ConditionalStringHandler)][1]. | | [WHERE(SqlBuilder.ClauseStringHandler<WHERE>)][3] | Appends the WHERE clause using the provided interpolated string *handler*. | | [WHERE(String)][4] | Appends the WHERE clause using the provided *text*. | Syntax ------ ```csharp public SqlBuilder WHERE() ``` #### Return Value [SqlBuilder][5] A reference to this instance after the operation has completed. See Also -------- #### Reference [SqlBuilder Class][5] [DbExtensions Namespace][2] [1]: _If.md [2]: ../README.md [3]: WHERE_1.md [4]: WHERE_2.md [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/WHERE_1.md ================================================ SqlBuilder.WHERE(SqlBuilder.ClauseStringHandler<SqlClause.WHERE>) Method =========================================================================== Appends the WHERE clause using the provided interpolated string *handler*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | [WHERE()][2] | Sets WHERE as the next clause, to be used by subsequent calls to clause continuation methods, such as [_If(Boolean, ConditionalStringHandler)][3]. | | **WHERE(SqlBuilder.ClauseStringHandler<WHERE>)** | Appends the WHERE clause using the provided interpolated string *handler*. | | [WHERE(String)][4] | Appends the WHERE clause using the provided *text*. | Syntax ------ ```csharp public SqlBuilder WHERE( ref ClauseStringHandler handler ) ``` #### Parameters ##### *handler*  ClauseStringHandler<WHERE> The interpolated string that represents the body of the WHERE clause. #### Return Value [SqlBuilder][5] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: WHERE.md [3]: _If.md [4]: WHERE_2.md [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/WHERE_2.md ================================================ SqlBuilder.WHERE(String) Method =============================== Appends the WHERE clause using the provided *text*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | [WHERE()][2] | Sets WHERE as the next clause, to be used by subsequent calls to clause continuation methods, such as [_If(Boolean, ConditionalStringHandler)][3]. | | [WHERE(SqlBuilder.ClauseStringHandler<WHERE>)][4] | Appends the WHERE clause using the provided interpolated string *handler*. | | **WHERE(String)** | Appends the WHERE clause using the provided *text*. | Syntax ------ ```csharp public SqlBuilder WHERE( string? text ) ``` #### Parameters ##### *text*  [String][5] The text that represents the body of the WHERE clause. #### Return Value [SqlBuilder][6] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: WHERE.md [3]: _If.md [4]: WHERE_1.md [5]: https://learn.microsoft.com/dotnet/api/system.string [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/WITH.md ================================================ SqlBuilder.WITH(SqlBuilder.ClauseStringHandler<SqlClause.WITH>) Method ========================================================================= Appends the WITH clause using the provided interpolated string *handler*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------- | ---------------------------------------------------------------------------------- | | **WITH(SqlBuilder.ClauseStringHandler<WITH>)** | Appends the WITH clause using the provided interpolated string *handler*. | | [WITH(String)][2] | Appends the WITH clause using the provided *text*. | | [WITH(String, SqlBuilder)][3] | Appends the WITH clause using the provided *subQuery* as body named after *alias*. | | [WITH(String, SqlSet)][4] | Appends the WITH clause using the provided *subQuery* as body named after *alias*. | Syntax ------ ```csharp public SqlBuilder WITH( ref ClauseStringHandler handler ) ``` #### Parameters ##### *handler*  ClauseStringHandler<WITH> The interpolated string that represents the body of the WITH clause. #### Return Value [SqlBuilder][5] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: WITH_1.md [3]: WITH_2.md [4]: WITH_3.md [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/WITH_1.md ================================================ SqlBuilder.WITH(String) Method ============================== Appends the WITH clause using the provided *text*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------- | ---------------------------------------------------------------------------------- | | [WITH(SqlBuilder.ClauseStringHandler<WITH>)][2] | Appends the WITH clause using the provided interpolated string *handler*. | | **WITH(String)** | Appends the WITH clause using the provided *text*. | | [WITH(String, SqlBuilder)][3] | Appends the WITH clause using the provided *subQuery* as body named after *alias*. | | [WITH(String, SqlSet)][4] | Appends the WITH clause using the provided *subQuery* as body named after *alias*. | Syntax ------ ```csharp public SqlBuilder WITH( string? text ) ``` #### Parameters ##### *text*  [String][5] The text that represents the body of the WITH clause. #### Return Value [SqlBuilder][6] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: WITH.md [3]: WITH_2.md [4]: WITH_3.md [5]: https://learn.microsoft.com/dotnet/api/system.string [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/WITH_2.md ================================================ SqlBuilder.WITH(String, SqlBuilder) Method ========================================== Appends the WITH clause using the provided *subQuery* as body named after *alias*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------- | ---------------------------------------------------------------------------------- | | [WITH(SqlBuilder.ClauseStringHandler<WITH>)][2] | Appends the WITH clause using the provided interpolated string *handler*. | | [WITH(String)][3] | Appends the WITH clause using the provided *text*. | | **WITH(String, SqlBuilder)** | Appends the WITH clause using the provided *subQuery* as body named after *alias*. | | [WITH(String, SqlSet)][4] | Appends the WITH clause using the provided *subQuery* as body named after *alias*. | Syntax ------ ```csharp public SqlBuilder WITH( string alias, SqlBuilder subQuery ) ``` #### Parameters ##### *alias*  [String][5] The alias of the sub-query. ##### *subQuery*  [SqlBuilder][6] The sub-query to use as the body of the WITH clause. #### Return Value [SqlBuilder][6] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: WITH.md [3]: WITH_1.md [4]: WITH_3.md [5]: https://learn.microsoft.com/dotnet/api/system.string [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/WITH_3.md ================================================ SqlBuilder.WITH(String, SqlSet) Method ====================================== Appends the WITH clause using the provided *subQuery* as body named after *alias*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------- | ---------------------------------------------------------------------------------- | | [WITH(SqlBuilder.ClauseStringHandler<WITH>)][2] | Appends the WITH clause using the provided interpolated string *handler*. | | [WITH(String)][3] | Appends the WITH clause using the provided *text*. | | [WITH(String, SqlBuilder)][4] | Appends the WITH clause using the provided *subQuery* as body named after *alias*. | | **WITH(String, SqlSet)** | Appends the WITH clause using the provided *subQuery* as body named after *alias*. | Syntax ------ ```csharp public SqlBuilder WITH( string alias, SqlSet subQuery ) ``` #### Parameters ##### *alias*  [String][5] The alias of the sub-query. ##### *subQuery*  [SqlSet][6] The sub-query to use as the body of the WITH clause. #### Return Value [SqlBuilder][7] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: WITH.md [3]: WITH_1.md [4]: WITH_2.md [5]: https://learn.microsoft.com/dotnet/api/system.string [6]: ../SqlSet/README.md [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/_.md ================================================ SqlBuilder._(SqlBuilder.ClauseStringHandler<SqlClause.Current>) Method ========================================================================= Appends the interpolated string *handler* to the current clause. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------- | ---------------------------------------------------------------- | | **_(SqlBuilder.ClauseStringHandler<Current>)** | Appends the interpolated string *handler* to the current clause. | | [_(String)][2] | Appends the *text* to the current clause. | Syntax ------ ```csharp public SqlBuilder _( ref ClauseStringHandler handler ) ``` #### Parameters ##### *handler*  ClauseStringHandler<Current> The interpolated string that represents the body of the current clause. #### Return Value [SqlBuilder][3] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: __1.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/_Else.md ================================================ SqlBuilder._Else Method ======================= Appends *handler* to the current clause if an antecedent call to [_If(Boolean, ConditionalStringHandler)][1] or [_ElseIf(Boolean, ConditionalElseStringHandler)][2] used a `false` condition **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlBuilder _Else( ref ConditionalElseStringHandler handler ) ``` #### Parameters ##### *handler*  ConditionalElseStringHandler The interpolated string that represents the body of the current clause. #### Return Value [SqlBuilder][4] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][4] [DbExtensions Namespace][3] [1]: _If.md [2]: _ElseIf.md [3]: ../README.md [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/_ElseIf.md ================================================ SqlBuilder._ElseIf Method ========================= Appends *handler* to the current clause if *condition* is `true` and an antecedent call to [_If(Boolean, ConditionalStringHandler)][1] or **_ElseIf(Boolean, ConditionalElseStringHandler)** used a `false` condition. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlBuilder _ElseIf( bool condition, ref ConditionalElseStringHandler handler ) ``` #### Parameters ##### *condition*  [Boolean][3] `true` to append *handler* to the current clause; otherwise, `false`. ##### *handler*  ConditionalElseStringHandler The interpolated string that represents the body of the current clause. #### Return Value [SqlBuilder][4] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][4] [DbExtensions Namespace][2] [1]: _If.md [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.boolean [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/_If.md ================================================ SqlBuilder._If Method ===================== Appends the interpolated string *handler* to the current clause if *condition* is `true`. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlBuilder _If( bool condition, ref ConditionalStringHandler handler ) ``` #### Parameters ##### *condition*  [Boolean][2] `true` to append *handler* to the current clause; otherwise, `false`. ##### *handler*  ConditionalStringHandler The interpolated string that represents the body of the current clause. #### Return Value [SqlBuilder][3] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.boolean [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlBuilder/__1.md ================================================ SqlBuilder._(String) Method =========================== Appends the *text* to the current clause. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------- | ---------------------------------------------------------------- | | [_(SqlBuilder.ClauseStringHandler<Current>)][2] | Appends the interpolated string *handler* to the current clause. | | **_(String)** | Appends the *text* to the current clause. | Syntax ------ ```csharp public SqlBuilder _( string? text ) ``` #### Parameters ##### *text*  [String][3] The text that represents the body of the current clause. #### Return Value [SqlBuilder][4] A reference to this instance after the append operation has completed. See Also -------- #### Reference [SqlBuilder Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: _.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlClause/Instance__1.md ================================================ SqlClause.Instance<TClause> Method ===================================== Gets a singleton instance of the clause identified by TClause. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public static TClause Instance() where TClause : new(), SqlClause ``` #### Type Parameters ##### *TClause* The type of the clause. #### Return Value **TClause** An instance of TClause. See Also -------- #### Reference [SqlClause Class][2] [DbExtensions Namespace][1] [1]: ../README.md [2]: README.md ================================================ FILE: docs/api/DbExtensions/SqlClause/Name.md ================================================ SqlClause.Name Property ======================= The name of the clause. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string? Name { get; init; } ``` #### Property Value [String][2] See Also -------- #### Reference [SqlClause Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlClause/README.md ================================================ SqlClause Class =============== Provides information about a SQL clause. Used by [SqlBuilder][1]. Inheritance Hierarchy --------------------- [System.Object][2]   **DbExtensions.SqlClause** **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public abstract class SqlClause : IEquatable ``` The **SqlClause** type exposes the following members. Constructors ------------ | Name | Description | | -------------- | ----------------------------------------------------------------- | | [SqlClause][4] | Provides information about a SQL clause. Used by [SqlBuilder][1]. | Properties ---------- | Name | Description | | -------------- | ---------------------------------------- | | [Name][5] | The name of the clause. | | [Separator][6] | The string to use for consecutive calls. | Methods ------- | Name | Description | | ------------------------- | -------------------------------------------------------------- | | [Instance<TClause>][7] | Gets a singleton instance of the clause identified by TClause. | See Also -------- #### Reference [DbExtensions Namespace][3] [1]: ../SqlBuilder/README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: ../README.md [4]: _ctor.md [5]: Name.md [6]: Separator.md [7]: Instance__1.md ================================================ FILE: docs/api/DbExtensions/SqlClause/Separator.md ================================================ SqlClause.Separator Property ============================ The string to use for consecutive calls. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string? Separator { get; init; } ``` #### Property Value [String][2] See Also -------- #### Reference [SqlClause Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlClause/_ctor.md ================================================ SqlClause Constructor ===================== Provides information about a SQL clause. Used by [SqlBuilder][1]. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp protected SqlClause( string? Name, string? Separator ) ``` #### Parameters ##### *Name*  [String][3] The name of the clause. ##### *Separator*  [String][3] The string to use for consecutive calls. See Also -------- #### Reference [SqlClause Class][4] [DbExtensions Namespace][2] [1]: ../SqlBuilder/README.md [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/All.md ================================================ SqlSet.All(SqlSet.OperatorStringHandler) Method =============================================== Determines whether all elements of the set satisfy a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------ | --------------------------------------------------------------- | | **All(OperatorStringHandler)** | Determines whether all elements of the set satisfy a condition. | | [All(String)][2] | Determines whether all elements of the set satisfy a condition. | Syntax ------ ```csharp public bool All( ref OperatorStringHandler predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [Boolean][3] `true` if every element of the set passes the test in the specified *predicate*, or if the set is empty; otherwise, `false`. See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: All_1.md [3]: https://learn.microsoft.com/dotnet/api/system.boolean [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/AllAsync.md ================================================ SqlSet.AllAsync(SqlSet.OperatorStringHandler, CancellationToken) Method ======================================================================= Determines whether all elements of the set satisfy a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------ | --------------------------------------------------------------- | | **AllAsync(OperatorStringHandler, CancellationToken)** | Determines whether all elements of the set satisfy a condition. | | [AllAsync(String, CancellationToken)][2] | Determines whether all elements of the set satisfy a condition. | Syntax ------ ```csharp public ValueTask AllAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[Boolean][6]> `true` if every element of the set passes the test in the specified *predicate*, or if the set is empty; otherwise, `false`. See Also -------- #### Reference [SqlSet Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: AllAsync_1.md [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.boolean [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/AllAsync_1.md ================================================ SqlSet.AllAsync(String, CancellationToken) Method ================================================= Determines whether all elements of the set satisfy a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------- | --------------------------------------------------------------- | | [AllAsync(OperatorStringHandler, CancellationToken)][2] | Determines whether all elements of the set satisfy a condition. | | **AllAsync(String, CancellationToken)** | Determines whether all elements of the set satisfy a condition. | Syntax ------ ```csharp public ValueTask AllAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][3] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Boolean][7]> `true` if every element of the set passes the test in the specified *predicate*, or if the set is empty; otherwise, `false`. See Also -------- #### Reference [SqlSet Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: AllAsync.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.boolean [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/All_1.md ================================================ SqlSet.All(String) Method ========================= Determines whether all elements of the set satisfy a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------- | --------------------------------------------------------------- | | [All(OperatorStringHandler)][2] | Determines whether all elements of the set satisfy a condition. | | **All(String)** | Determines whether all elements of the set satisfy a condition. | Syntax ------ ```csharp public bool All( string predicate ) ``` #### Parameters ##### *predicate*  [String][3] A SQL expression to test each row for a condition. #### Return Value [Boolean][4] `true` if every element of the set passes the test in the specified *predicate*, or if the set is empty; otherwise, `false`. See Also -------- #### Reference [SqlSet Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: All.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: https://learn.microsoft.com/dotnet/api/system.boolean [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Any.md ================================================ SqlSet.Any Method ================= Determines whether the set contains any elements. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------- | ---------------------------------------------------------------- | | **Any()** | Determines whether the set contains any elements. | | [Any(OperatorStringHandler)][2] | Determines whether any element of the set satisfies a condition. | | [Any(String)][3] | Determines whether any element of the set satisfies a condition. | Syntax ------ ```csharp public bool Any() ``` #### Return Value [Boolean][4] `true` if the sequence contains any elements; otherwise, `false`. See Also -------- #### Reference [SqlSet Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: Any_1.md [3]: Any_2.md [4]: https://learn.microsoft.com/dotnet/api/system.boolean [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/AnyAsync.md ================================================ SqlSet.AnyAsync(SqlSet.OperatorStringHandler, CancellationToken) Method ======================================================================= Determines whether any element of the set satisfies a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------ | ---------------------------------------------------------------- | | [AnyAsync(CancellationToken)][2] | Determines whether the set contains any elements. | | **AnyAsync(OperatorStringHandler, CancellationToken)** | Determines whether any element of the set satisfies a condition. | | [AnyAsync(String, CancellationToken)][3] | Determines whether any element of the set satisfies a condition. | Syntax ------ ```csharp public ValueTask AnyAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Boolean][7]> `true` if any elements in the set pass the test in the specified *predicate*; otherwise, `false`. See Also -------- #### Reference [SqlSet Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: AnyAsync_2.md [3]: AnyAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.boolean [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/AnyAsync_1.md ================================================ SqlSet.AnyAsync(String, CancellationToken) Method ================================================= Determines whether any element of the set satisfies a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------- | ---------------------------------------------------------------- | | [AnyAsync(CancellationToken)][2] | Determines whether the set contains any elements. | | [AnyAsync(OperatorStringHandler, CancellationToken)][3] | Determines whether any element of the set satisfies a condition. | | **AnyAsync(String, CancellationToken)** | Determines whether any element of the set satisfies a condition. | Syntax ------ ```csharp public ValueTask AnyAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[Boolean][8]> `true` if any elements in the set pass the test in the specified *predicate*; otherwise, `false`. See Also -------- #### Reference [SqlSet Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: AnyAsync_2.md [3]: AnyAsync.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: https://learn.microsoft.com/dotnet/api/system.boolean [9]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/AnyAsync_2.md ================================================ SqlSet.AnyAsync(CancellationToken) Method ========================================= Determines whether the set contains any elements. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------- | ---------------------------------------------------------------- | | **AnyAsync(CancellationToken)** | Determines whether the set contains any elements. | | [AnyAsync(OperatorStringHandler, CancellationToken)][2] | Determines whether any element of the set satisfies a condition. | | [AnyAsync(String, CancellationToken)][3] | Determines whether any element of the set satisfies a condition. | Syntax ------ ```csharp public ValueTask AnyAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Boolean][7]> `true` if the sequence contains any elements; otherwise, `false`. See Also -------- #### Reference [SqlSet Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: AnyAsync.md [3]: AnyAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.boolean [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Any_1.md ================================================ SqlSet.Any(SqlSet.OperatorStringHandler) Method =============================================== Determines whether any element of the set satisfies a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------ | ---------------------------------------------------------------- | | [Any()][2] | Determines whether the set contains any elements. | | **Any(OperatorStringHandler)** | Determines whether any element of the set satisfies a condition. | | [Any(String)][3] | Determines whether any element of the set satisfies a condition. | Syntax ------ ```csharp public bool Any( ref OperatorStringHandler predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [Boolean][4] `true` if any elements in the set pass the test in the specified *predicate*; otherwise, `false`. See Also -------- #### Reference [SqlSet Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: Any.md [3]: Any_2.md [4]: https://learn.microsoft.com/dotnet/api/system.boolean [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Any_2.md ================================================ SqlSet.Any(String) Method ========================= Determines whether any element of the set satisfies a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------- | ---------------------------------------------------------------- | | [Any()][2] | Determines whether the set contains any elements. | | [Any(OperatorStringHandler)][3] | Determines whether any element of the set satisfies a condition. | | **Any(String)** | Determines whether any element of the set satisfies a condition. | Syntax ------ ```csharp public bool Any( string predicate ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. #### Return Value [Boolean][5] `true` if any elements in the set pass the test in the specified *predicate*; otherwise, `false`. See Also -------- #### Reference [SqlSet Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: Any.md [3]: Any_1.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.boolean [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/AsAsyncEnumerable.md ================================================ SqlSet.AsAsyncEnumerable Method =============================== Gets all elements in the set. The query is deferred-executed. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public IAsyncEnumerable AsAsyncEnumerable() ``` #### Return Value [IAsyncEnumerable][2]<[Object][3]> All elements in the set. See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerable-1 [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/AsEnumerable.md ================================================ SqlSet.AsEnumerable Method ========================== Gets all elements in the set. The query is deferred-executed. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public IEnumerable AsEnumerable() ``` #### Return Value [IEnumerable][2]<[Object][3]> All elements in the set. See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Cast.md ================================================ SqlSet.Cast(Type) Method ======================== Casts the elements of the set to the specified type. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------- | ---------------------------------------------------- | | **Cast(Type)** | Casts the elements of the set to the specified type. | | [Cast<TResult>()][2] | Casts the elements of the set to the specified type. | Syntax ------ ```csharp public SqlSet Cast( Type resultType ) ``` #### Parameters ##### *resultType*  [Type][3] The type to cast the elements of the set to. #### Return Value [SqlSet][4] A new [SqlSet][4] that contains each element of the current set cast to the specified type. See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: Cast__1.md [3]: https://learn.microsoft.com/dotnet/api/system.type [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Cast__1.md ================================================ SqlSet.Cast<TResult> Method ============================== Casts the elements of the set to the specified type. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------- | ---------------------------------------------------- | | [Cast(Type)][2] | Casts the elements of the set to the specified type. | | **Cast<TResult>()** | Casts the elements of the set to the specified type. | Syntax ------ ```csharp public SqlSet Cast() ``` #### Type Parameters ##### *TResult* The type to cast the elements of the set to. #### Return Value [SqlSet][3]<**TResult**> A new [SqlSet<TResult>][3] that contains each element of the current set cast to the specified type. See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: Cast.md [3]: ../SqlSet_1/README.md [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Contains.md ================================================ SqlSet.Contains Method ====================== Checks the existance of the *entity*, using the primary key value. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool Contains( Object entity ) ``` #### Parameters ##### *entity*  [Object][2] The entity whose existance is to be checked. #### Return Value [Boolean][3] `true` if the primary key value exists in the database; otherwise, `false`. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][4] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.boolean [4]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/ContainsAsync.md ================================================ SqlSet.ContainsAsync Method =========================== Checks the existance of the *entity*, using the primary key value. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask ContainsAsync( Object entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [Object][2] The entity whose existance is to be checked. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[Boolean][6]> `true` if the primary key value exists in the database; otherwise, `false`. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][7] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.boolean [7]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/ContainsKey.md ================================================ SqlSet.ContainsKey Method ========================= Checks the existance of an entity whose primary matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool ContainsKey( Object id ) ``` #### Parameters ##### *id*  [Object][2] The primary key value. #### Return Value [Boolean][3] `true` if the primary key value exists in the database; otherwise, `false`. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][4] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.boolean [4]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/ContainsKeyAsync.md ================================================ SqlSet.ContainsKeyAsync Method ============================== Checks the existance of an entity whose primary matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask ContainsKeyAsync( Object id, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *id*  [Object][2] The primary key value. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[Boolean][6]> `true` if the primary key value exists in the database; otherwise, `false`. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][7] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.boolean [7]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Count.md ================================================ SqlSet.Count Method =================== Returns the number of elements in the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------- | ---------------------------------------------------------------------------------- | | **Count()** | Returns the number of elements in the set. | | [Count(OperatorStringHandler)][2] | Returns a number that represents how many elements in the set satisfy a condition. | | [Count(String)][3] | Returns a number that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public int Count() ``` #### Return Value [Int32][4] The number of elements in the set. Exceptions ---------- | Exception | Condition | | ---------------------- | ---------------------------------------------------- | | [OverflowException][5] | The number of elements is larger than [MaxValue][6]. | See Also -------- #### Reference [SqlSet Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: Count_1.md [3]: Count_2.md [4]: https://learn.microsoft.com/dotnet/api/system.int32 [5]: https://learn.microsoft.com/dotnet/api/system.overflowexception [6]: https://learn.microsoft.com/dotnet/api/system.int32.maxvalue [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/CountAsync.md ================================================ SqlSet.CountAsync(SqlSet.OperatorStringHandler, CancellationToken) Method ========================================================================= Returns a number that represents how many elements in the set satisfy a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------------- | ---------------------------------------------------------------------------------- | | [CountAsync(CancellationToken)][2] | Returns the number of elements in the set. | | **CountAsync(OperatorStringHandler, CancellationToken)** | Returns a number that represents how many elements in the set satisfy a condition. | | [CountAsync(String, CancellationToken)][3] | Returns a number that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public ValueTask CountAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Int32][7]> A number that represents how many elements in the set satisfy the condition in the *predicate*. Exceptions ---------- | Exception | Condition | | ---------------------- | ------------------------------------------------------ | | [OverflowException][8] | The number of matching elements exceeds [MaxValue][9]. | See Also -------- #### Reference [SqlSet Class][10] [DbExtensions Namespace][1] [1]: ../README.md [2]: CountAsync_2.md [3]: CountAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.int32 [8]: https://learn.microsoft.com/dotnet/api/system.overflowexception [9]: https://learn.microsoft.com/dotnet/api/system.int32.maxvalue [10]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/CountAsync_1.md ================================================ SqlSet.CountAsync(String, CancellationToken) Method =================================================== Returns a number that represents how many elements in the set satisfy a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------- | ---------------------------------------------------------------------------------- | | [CountAsync(CancellationToken)][2] | Returns the number of elements in the set. | | [CountAsync(OperatorStringHandler, CancellationToken)][3] | Returns a number that represents how many elements in the set satisfy a condition. | | **CountAsync(String, CancellationToken)** | Returns a number that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public ValueTask CountAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[Int32][8]> A number that represents how many elements in the set satisfy the condition in the *predicate*. Exceptions ---------- | Exception | Condition | | ---------------------- | ------------------------------------------------------- | | [OverflowException][9] | The number of matching elements exceeds [MaxValue][10]. | See Also -------- #### Reference [SqlSet Class][11] [DbExtensions Namespace][1] [1]: ../README.md [2]: CountAsync_2.md [3]: CountAsync.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: https://learn.microsoft.com/dotnet/api/system.int32 [9]: https://learn.microsoft.com/dotnet/api/system.overflowexception [10]: https://learn.microsoft.com/dotnet/api/system.int32.maxvalue [11]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/CountAsync_2.md ================================================ SqlSet.CountAsync(CancellationToken) Method =========================================== Returns the number of elements in the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------- | ---------------------------------------------------------------------------------- | | **CountAsync(CancellationToken)** | Returns the number of elements in the set. | | [CountAsync(OperatorStringHandler, CancellationToken)][2] | Returns a number that represents how many elements in the set satisfy a condition. | | [CountAsync(String, CancellationToken)][3] | Returns a number that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public ValueTask CountAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Int32][7]> The number of elements in the set. Exceptions ---------- | Exception | Condition | | ---------------------- | ---------------------------------------------------- | | [OverflowException][8] | The number of elements is larger than [MaxValue][9]. | See Also -------- #### Reference [SqlSet Class][10] [DbExtensions Namespace][1] [1]: ../README.md [2]: CountAsync.md [3]: CountAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.int32 [8]: https://learn.microsoft.com/dotnet/api/system.overflowexception [9]: https://learn.microsoft.com/dotnet/api/system.int32.maxvalue [10]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Count_1.md ================================================ SqlSet.Count(SqlSet.OperatorStringHandler) Method ================================================= Returns a number that represents how many elements in the set satisfy a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------- | ---------------------------------------------------------------------------------- | | [Count()][2] | Returns the number of elements in the set. | | **Count(OperatorStringHandler)** | Returns a number that represents how many elements in the set satisfy a condition. | | [Count(String)][3] | Returns a number that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public int Count( ref OperatorStringHandler predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [Int32][4] A number that represents how many elements in the set satisfy the condition in the *predicate*. Exceptions ---------- | Exception | Condition | | ---------------------- | ------------------------------------------------------ | | [OverflowException][5] | The number of matching elements exceeds [MaxValue][6]. | See Also -------- #### Reference [SqlSet Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: Count.md [3]: Count_2.md [4]: https://learn.microsoft.com/dotnet/api/system.int32 [5]: https://learn.microsoft.com/dotnet/api/system.overflowexception [6]: https://learn.microsoft.com/dotnet/api/system.int32.maxvalue [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Count_2.md ================================================ SqlSet.Count(String) Method =========================== Returns a number that represents how many elements in the set satisfy a condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------- | ---------------------------------------------------------------------------------- | | [Count()][2] | Returns the number of elements in the set. | | [Count(OperatorStringHandler)][3] | Returns a number that represents how many elements in the set satisfy a condition. | | **Count(String)** | Returns a number that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public int Count( string predicate ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. #### Return Value [Int32][5] A number that represents how many elements in the set satisfy the condition in the *predicate*. Exceptions ---------- | Exception | Condition | | ---------------------- | ------------------------------------------------------ | | [OverflowException][6] | The number of matching elements exceeds [MaxValue][7]. | See Also -------- #### Reference [SqlSet Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: Count.md [3]: Count_1.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.int32 [6]: https://learn.microsoft.com/dotnet/api/system.overflowexception [7]: https://learn.microsoft.com/dotnet/api/system.int32.maxvalue [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Database.md ================================================ SqlSet.Database Property ======================== The [Database][1] this set is connected to. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public Database Database { get; } ``` #### Property Value [Database][1] See Also -------- #### Reference [SqlSet Class][3] [DbExtensions Namespace][2] [1]: ../Database/README.md [2]: ../README.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Find.md ================================================ SqlSet.Find Method ================== Gets the entity whose primary key matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public Object? Find( Object id ) ``` #### Parameters ##### *id*  [Object][2] The primary key value. #### Return Value [Object][2] The entity whose primary key matches the *id* parameter, or null if the *id* does not exist. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][3] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/FindAsync.md ================================================ SqlSet.FindAsync Method ======================= Gets the entity whose primary key matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask FindAsync( Object id, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *id*  [Object][2] The primary key value. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[Object][2]> The entity whose primary key matches the *id* parameter, or null if the *id* does not exist. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][6] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/First.md ================================================ SqlSet.First Method =================== Returns the first element of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------- | -------------------------------------------------------------------------- | | **First()** | Returns the first element of the set. | | [First(OperatorStringHandler)][2] | Returns the first element in the set that satisfies a specified condition. | | [First(String)][3] | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public Object First() ``` #### Return Value [Object][4] The first element in the set. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------- | | [InvalidOperationException][5] | The set is empty. | See Also -------- #### Reference [SqlSet Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: First_1.md [3]: First_2.md [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/FirstAsync.md ================================================ SqlSet.FirstAsync(SqlSet.OperatorStringHandler, CancellationToken) Method ========================================================================= Returns the first element in the set that satisfies a specified condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------------- | -------------------------------------------------------------------------- | | [FirstAsync(CancellationToken)][2] | Returns the first element of the set. | | **FirstAsync(OperatorStringHandler, CancellationToken)** | Returns the first element in the set that satisfies a specified condition. | | [FirstAsync(String, CancellationToken)][3] | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public ValueTask FirstAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Object][7]> The first element in the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------------------------------------------------------------- | | [InvalidOperationException][8] | No element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstAsync_2.md [3]: FirstAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.object [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [9]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/FirstAsync_1.md ================================================ SqlSet.FirstAsync(String, CancellationToken) Method =================================================== Returns the first element in the set that satisfies a specified condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------- | -------------------------------------------------------------------------- | | [FirstAsync(CancellationToken)][2] | Returns the first element of the set. | | [FirstAsync(OperatorStringHandler, CancellationToken)][3] | Returns the first element in the set that satisfies a specified condition. | | **FirstAsync(String, CancellationToken)** | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public ValueTask FirstAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[Object][8]> The first element in the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------------------------------------------------------------- | | [InvalidOperationException][9] | No element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet Class][10] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstAsync_2.md [3]: FirstAsync.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: https://learn.microsoft.com/dotnet/api/system.object [9]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [10]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/FirstAsync_2.md ================================================ SqlSet.FirstAsync(CancellationToken) Method =========================================== Returns the first element of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------- | -------------------------------------------------------------------------- | | **FirstAsync(CancellationToken)** | Returns the first element of the set. | | [FirstAsync(OperatorStringHandler, CancellationToken)][2] | Returns the first element in the set that satisfies a specified condition. | | [FirstAsync(String, CancellationToken)][3] | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public ValueTask FirstAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Object][7]> The first element in the set. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------- | | [InvalidOperationException][8] | The set is empty. | See Also -------- #### Reference [SqlSet Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstAsync.md [3]: FirstAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.object [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [9]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/FirstOrDefault.md ================================================ SqlSet.FirstOrDefault Method ============================ Returns the first element of the set, or a default value if the set contains no elements. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | **FirstOrDefault()** | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefault(OperatorStringHandler)][2] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefault(String)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public Object? FirstOrDefault() ``` #### Return Value [Object][4] A default value if the set is empty; otherwise, the first element. See Also -------- #### Reference [SqlSet Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefault_1.md [3]: FirstOrDefault_2.md [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/FirstOrDefaultAsync.md ================================================ SqlSet.FirstOrDefaultAsync(SqlSet.OperatorStringHandler, CancellationToken) Method ================================================================================== Returns the first element of the set that satisfies a condition or a default value if no such element is found. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | [FirstOrDefaultAsync(CancellationToken)][2] | Returns the first element of the set, or a default value if the set contains no elements. | | **FirstOrDefaultAsync(OperatorStringHandler, CancellationToken)** | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefaultAsync(String, CancellationToken)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public ValueTask FirstOrDefaultAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Object][7]> A default value if the set is empty or if no element passes the test specified by *predicate*; otherwise, the first element that passes the test specified by *predicate*. See Also -------- #### Reference [SqlSet Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefaultAsync_2.md [3]: FirstOrDefaultAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.object [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/FirstOrDefaultAsync_1.md ================================================ SqlSet.FirstOrDefaultAsync(String, CancellationToken) Method ============================================================ Returns the first element of the set that satisfies a condition or a default value if no such element is found. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | [FirstOrDefaultAsync(CancellationToken)][2] | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefaultAsync(OperatorStringHandler, CancellationToken)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | **FirstOrDefaultAsync(String, CancellationToken)** | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public ValueTask FirstOrDefaultAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[Object][8]> A default value if the set is empty or if no element passes the test specified by *predicate*; otherwise, the first element that passes the test specified by *predicate*. See Also -------- #### Reference [SqlSet Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefaultAsync_2.md [3]: FirstOrDefaultAsync.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: https://learn.microsoft.com/dotnet/api/system.object [9]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/FirstOrDefaultAsync_2.md ================================================ SqlSet.FirstOrDefaultAsync(CancellationToken) Method ==================================================== Returns the first element of the set, or a default value if the set contains no elements. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | **FirstOrDefaultAsync(CancellationToken)** | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefaultAsync(OperatorStringHandler, CancellationToken)][2] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefaultAsync(String, CancellationToken)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public ValueTask FirstOrDefaultAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Object][7]> A default value if the set is empty; otherwise, the first element. See Also -------- #### Reference [SqlSet Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefaultAsync.md [3]: FirstOrDefaultAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.object [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/FirstOrDefault_1.md ================================================ SqlSet.FirstOrDefault(SqlSet.OperatorStringHandler) Method ========================================================== Returns the first element of the set that satisfies a condition or a default value if no such element is found. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | [FirstOrDefault()][2] | Returns the first element of the set, or a default value if the set contains no elements. | | **FirstOrDefault(OperatorStringHandler)** | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefault(String)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public Object? FirstOrDefault( ref OperatorStringHandler? predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [Object][4] A default value if the set is empty or if no element passes the test specified by *predicate*; otherwise, the first element that passes the test specified by *predicate*. See Also -------- #### Reference [SqlSet Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefault.md [3]: FirstOrDefault_2.md [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/FirstOrDefault_2.md ================================================ SqlSet.FirstOrDefault(String) Method ==================================== Returns the first element of the set that satisfies a condition or a default value if no such element is found. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | [FirstOrDefault()][2] | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefault(OperatorStringHandler)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | **FirstOrDefault(String)** | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public Object? FirstOrDefault( string predicate ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. #### Return Value [Object][5] A default value if the set is empty or if no element passes the test specified by *predicate*; otherwise, the first element that passes the test specified by *predicate*. See Also -------- #### Reference [SqlSet Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefault.md [3]: FirstOrDefault_1.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.object [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/First_1.md ================================================ SqlSet.First(SqlSet.OperatorStringHandler) Method ================================================= Returns the first element in the set that satisfies a specified condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------- | -------------------------------------------------------------------------- | | [First()][2] | Returns the first element of the set. | | **First(OperatorStringHandler)** | Returns the first element in the set that satisfies a specified condition. | | [First(String)][3] | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public Object First( ref OperatorStringHandler predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [Object][4] The first element in the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------------------------------------------------------------- | | [InvalidOperationException][5] | No element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: First.md [3]: First_2.md [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/First_2.md ================================================ SqlSet.First(String) Method =========================== Returns the first element in the set that satisfies a specified condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------- | -------------------------------------------------------------------------- | | [First()][2] | Returns the first element of the set. | | [First(OperatorStringHandler)][3] | Returns the first element in the set that satisfies a specified condition. | | **First(String)** | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public Object First( string predicate ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. #### Return Value [Object][5] The first element in the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------------------------------------------------------------- | | [InvalidOperationException][6] | No element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: First.md [3]: First_1.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.object [6]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/GetAsyncEnumerator.md ================================================ SqlSet.GetAsyncEnumerator Method ================================ Returns an async enumerator that iterates through the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public IAsyncEnumerator GetAsyncEnumerator( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][2]  (Optional) The [CancellationToken][2] to monitor for cancellation requests. The default is [None][3]. #### Return Value [IAsyncEnumerator][4]<[Object][5]> A [IAsyncEnumerator<T>][4] for the set. See Also -------- #### Reference [SqlSet Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [4]: https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerator-1 [5]: https://learn.microsoft.com/dotnet/api/system.object [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/GetDefiningQuery.md ================================================ SqlSet.GetDefiningQuery Method ============================== Returns the SQL query that is the source of data for the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlBuilder GetDefiningQuery() ``` #### Return Value [SqlBuilder][2] The SQL query that is the source of data for the set See Also -------- #### Reference [SqlSet Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: ../SqlBuilder/README.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/GetEnumerator.md ================================================ SqlSet.GetEnumerator Method =========================== Returns an enumerator that iterates through the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public IEnumerator GetEnumerator() ``` #### Return Value [IEnumerator][2]<[Object][3]> A [IEnumerator<T>][2] for the set. See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerator-1 [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Include.md ================================================ SqlSet.Include Method ===================== Specifies the related objects to include in the query results. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlSet Include( string path ) ``` #### Parameters ##### *path*  [String][2] Dot-separated list of related objects to return in the query results. #### Return Value [SqlSet][3] A new [SqlSet][3] with the defined query path. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][4] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md [4]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet/IncludeMany.md ================================================ SqlSet.IncludeMany Method ========================= Specifies which collections to include in the query results. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlSet IncludeMany( string path, Func? manySetup = null ) ``` #### Parameters ##### *path*  [String][2] Dot-separated list of one or more related objects that ends with the collection to load. ##### *manySetup*  [Func][3]<[SqlSet][4], [SqlSet][4]>  (Optional) A function to customize how the collection is loaded. #### Return Value [SqlSet][4] A new [SqlSet][4]. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][5] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: https://learn.microsoft.com/dotnet/api/system.func-2 [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet/LongCount.md ================================================ SqlSet.LongCount Method ======================= Returns an [Int64][1] that represents the total number of elements in the set. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------- | --------------------------------------------------------------------------------------- | | **LongCount()** | Returns an [Int64][1] that represents the total number of elements in the set. | | [LongCount(OperatorStringHandler)][3] | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | | [LongCount(String)][4] | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public long LongCount() ``` #### Return Value [Int64][1] The number of elements in the set. Exceptions ---------- | Exception | Condition | | ---------------------- | ---------------------------------------------------- | | [OverflowException][5] | The number of elements is larger than [MaxValue][6]. | See Also -------- #### Reference [SqlSet Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.int64 [2]: ../README.md [3]: LongCount_1.md [4]: LongCount_2.md [5]: https://learn.microsoft.com/dotnet/api/system.overflowexception [6]: https://learn.microsoft.com/dotnet/api/system.int64.maxvalue [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/LongCountAsync.md ================================================ SqlSet.LongCountAsync(SqlSet.OperatorStringHandler, CancellationToken) Method ============================================================================= Returns an [Int64][1] that represents how many elements in the set satisfy a condition. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------ | --------------------------------------------------------------------------------------- | | [LongCountAsync(CancellationToken)][3] | Returns an [Int64][1] that represents the total number of elements in the set. | | **LongCountAsync(OperatorStringHandler, CancellationToken)** | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | | [LongCountAsync(String, CancellationToken)][4] | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public ValueTask LongCountAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[Int64][1]> A number that represents how many elements in the set satisfy the condition in the *predicate*. Exceptions ---------- | Exception | Condition | | ---------------------- | ------------------------------------------------------ | | [OverflowException][8] | The number of matching elements exceeds [MaxValue][9]. | See Also -------- #### Reference [SqlSet Class][10] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.int64 [2]: ../README.md [3]: LongCountAsync_2.md [4]: LongCountAsync_1.md [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: https://learn.microsoft.com/dotnet/api/system.overflowexception [9]: https://learn.microsoft.com/dotnet/api/system.int64.maxvalue [10]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/LongCountAsync_1.md ================================================ SqlSet.LongCountAsync(String, CancellationToken) Method ======================================================= Returns an [Int64][1] that represents how many elements in the set satisfy a condition. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | [LongCountAsync(CancellationToken)][3] | Returns an [Int64][1] that represents the total number of elements in the set. | | [LongCountAsync(OperatorStringHandler, CancellationToken)][4] | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | | **LongCountAsync(String, CancellationToken)** | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public ValueTask LongCountAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][5] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][6]  (Optional) The [CancellationToken][6] to monitor for cancellation requests. The default is [None][7]. #### Return Value [ValueTask][8]<[Int64][1]> A number that represents how many elements in the set satisfy the condition in the *predicate*. Exceptions ---------- | Exception | Condition | | ---------------------- | ------------------------------------------------------- | | [OverflowException][9] | The number of matching elements exceeds [MaxValue][10]. | See Also -------- #### Reference [SqlSet Class][11] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.int64 [2]: ../README.md [3]: LongCountAsync_2.md [4]: LongCountAsync.md [5]: https://learn.microsoft.com/dotnet/api/system.string [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [7]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [8]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [9]: https://learn.microsoft.com/dotnet/api/system.overflowexception [10]: https://learn.microsoft.com/dotnet/api/system.int64.maxvalue [11]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/LongCountAsync_2.md ================================================ SqlSet.LongCountAsync(CancellationToken) Method =============================================== Returns an [Int64][1] that represents the total number of elements in the set. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | **LongCountAsync(CancellationToken)** | Returns an [Int64][1] that represents the total number of elements in the set. | | [LongCountAsync(OperatorStringHandler, CancellationToken)][3] | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | | [LongCountAsync(String, CancellationToken)][4] | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public ValueTask LongCountAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[Int64][1]> The number of elements in the set. Exceptions ---------- | Exception | Condition | | ---------------------- | ---------------------------------------------------- | | [OverflowException][8] | The number of elements is larger than [MaxValue][9]. | See Also -------- #### Reference [SqlSet Class][10] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.int64 [2]: ../README.md [3]: LongCountAsync.md [4]: LongCountAsync_1.md [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: https://learn.microsoft.com/dotnet/api/system.overflowexception [9]: https://learn.microsoft.com/dotnet/api/system.int64.maxvalue [10]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/LongCount_1.md ================================================ SqlSet.LongCount(SqlSet.OperatorStringHandler) Method ===================================================== Returns an [Int64][1] that represents how many elements in the set satisfy a condition. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------ | --------------------------------------------------------------------------------------- | | [LongCount()][3] | Returns an [Int64][1] that represents the total number of elements in the set. | | **LongCount(OperatorStringHandler)** | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | | [LongCount(String)][4] | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public long LongCount( ref OperatorStringHandler predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [Int64][1] A number that represents how many elements in the set satisfy the condition in the *predicate*. Exceptions ---------- | Exception | Condition | | ---------------------- | ------------------------------------------------------ | | [OverflowException][5] | The number of matching elements exceeds [MaxValue][6]. | See Also -------- #### Reference [SqlSet Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.int64 [2]: ../README.md [3]: LongCount.md [4]: LongCount_2.md [5]: https://learn.microsoft.com/dotnet/api/system.overflowexception [6]: https://learn.microsoft.com/dotnet/api/system.int64.maxvalue [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/LongCount_2.md ================================================ SqlSet.LongCount(String) Method =============================== Returns an [Int64][1] that represents how many elements in the set satisfy a condition. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------- | --------------------------------------------------------------------------------------- | | [LongCount()][3] | Returns an [Int64][1] that represents the total number of elements in the set. | | [LongCount(OperatorStringHandler)][4] | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | | **LongCount(String)** | Returns an [Int64][1] that represents how many elements in the set satisfy a condition. | Syntax ------ ```csharp public long LongCount( string predicate ) ``` #### Parameters ##### *predicate*  [String][5] A SQL expression to test each row for a condition. #### Return Value [Int64][1] A number that represents how many elements in the set satisfy the condition in the *predicate*. Exceptions ---------- | Exception | Condition | | ---------------------- | ------------------------------------------------------ | | [OverflowException][6] | The number of matching elements exceeds [MaxValue][7]. | See Also -------- #### Reference [SqlSet Class][8] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.int64 [2]: ../README.md [3]: LongCount.md [4]: LongCount_1.md [5]: https://learn.microsoft.com/dotnet/api/system.string [6]: https://learn.microsoft.com/dotnet/api/system.overflowexception [7]: https://learn.microsoft.com/dotnet/api/system.int64.maxvalue [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/OrderBy.md ================================================ SqlSet.OrderBy(SqlSet.OperatorStringHandler) Method =================================================== Sorts the elements of the set according to the *columnList*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------- | ------------------------------------------------------------ | | **OrderBy(OperatorStringHandler)** | Sorts the elements of the set according to the *columnList*. | | [OrderBy(String)][2] | Sorts the elements of the set according to the *columnList*. | Syntax ------ ```csharp public SqlSet OrderBy( ref OperatorStringHandler columnList ) ``` #### Parameters ##### *columnList*  OperatorStringHandler The list of columns to base the sort on. #### Return Value [SqlSet][3] A new [SqlSet][3] whose elements are sorted according to *columnList*. See Also -------- #### Reference [SqlSet Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: OrderBy_1.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/OrderBy_1.md ================================================ SqlSet.OrderBy(String) Method ============================= Sorts the elements of the set according to the *columnList*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------- | ------------------------------------------------------------ | | [OrderBy(OperatorStringHandler)][2] | Sorts the elements of the set according to the *columnList*. | | **OrderBy(String)** | Sorts the elements of the set according to the *columnList*. | Syntax ------ ```csharp public SqlSet OrderBy( string columnList ) ``` #### Parameters ##### *columnList*  [String][3] The list of columns to base the sort on. #### Return Value [SqlSet][4] A new [SqlSet][4] whose elements are sorted according to *columnList*. See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: OrderBy.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/README.md ================================================ SqlSet Class ============ Represents an immutable, connected SQL query. This class cannot be instantiated, to get an instance use one of the [Database.From][1] or [Database.FromQuery][2] overloads. Inheritance Hierarchy --------------------- [System.Object][3]   **DbExtensions.SqlSet**     [DbExtensions.SqlSet<TResult>][4]     [DbExtensions.SqlTable][5] **Namespace:** [DbExtensions][6] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public class SqlSet ``` The **SqlSet** type exposes the following members. Properties ---------- | Name | Description | | --------------- | ---------------------------------------------------------------- | | [Database][7] | The [Database][8] this set is connected to. | | [ResultType][9] | The type of objects this set returns. This property can be null. | Methods ------- | Name | Description | | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [All(OperatorStringHandler)][10] | Determines whether all elements of the set satisfy a condition. | | [All(String)][11] | Determines whether all elements of the set satisfy a condition. | | [AllAsync(OperatorStringHandler, CancellationToken)][12] | Determines whether all elements of the set satisfy a condition. | | [AllAsync(String, CancellationToken)][13] | Determines whether all elements of the set satisfy a condition. | | [Any()][14] | Determines whether the set contains any elements. | | [Any(OperatorStringHandler)][15] | Determines whether any element of the set satisfies a condition. | | [Any(String)][16] | Determines whether any element of the set satisfies a condition. | | [AnyAsync(CancellationToken)][17] | Determines whether the set contains any elements. | | [AnyAsync(OperatorStringHandler, CancellationToken)][18] | Determines whether any element of the set satisfies a condition. | | [AnyAsync(String, CancellationToken)][19] | Determines whether any element of the set satisfies a condition. | | [AsAsyncEnumerable][20] | Gets all elements in the set. The query is deferred-executed. | | [AsEnumerable][21] | Gets all elements in the set. The query is deferred-executed. | | [Cast(Type)][22] | Casts the elements of the set to the specified type. | | [Cast<TResult>()][23] | Casts the elements of the set to the specified type. | | [Contains][24] | Checks the existance of the *entity*, using the primary key value. | | [ContainsAsync][25] | Checks the existance of the *entity*, using the primary key value. | | [ContainsKey][26] | Checks the existance of an entity whose primary matches the *id* parameter. | | [ContainsKeyAsync][27] | Checks the existance of an entity whose primary matches the *id* parameter. | | [Count()][28] | Returns the number of elements in the set. | | [Count(OperatorStringHandler)][29] | Returns a number that represents how many elements in the set satisfy a condition. | | [Count(String)][30] | Returns a number that represents how many elements in the set satisfy a condition. | | [CountAsync(CancellationToken)][31] | Returns the number of elements in the set. | | [CountAsync(OperatorStringHandler, CancellationToken)][32] | Returns a number that represents how many elements in the set satisfy a condition. | | [CountAsync(String, CancellationToken)][33] | Returns a number that represents how many elements in the set satisfy a condition. | | [Find][34] | Gets the entity whose primary key matches the *id* parameter. | | [FindAsync][35] | Gets the entity whose primary key matches the *id* parameter. | | [First()][36] | Returns the first element of the set. | | [First(OperatorStringHandler)][37] | Returns the first element in the set that satisfies a specified condition. | | [First(String)][38] | Returns the first element in the set that satisfies a specified condition. | | [FirstAsync(CancellationToken)][39] | Returns the first element of the set. | | [FirstAsync(OperatorStringHandler, CancellationToken)][40] | Returns the first element in the set that satisfies a specified condition. | | [FirstAsync(String, CancellationToken)][41] | Returns the first element in the set that satisfies a specified condition. | | [FirstOrDefault()][42] | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefault(OperatorStringHandler)][43] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefault(String)][44] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefaultAsync(CancellationToken)][45] | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefaultAsync(OperatorStringHandler, CancellationToken)][46] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefaultAsync(String, CancellationToken)][47] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [GetAsyncEnumerator][48] | Returns an async enumerator that iterates through the set. | | [GetDefiningQuery][49] | Returns the SQL query that is the source of data for the set. | | [GetEnumerator][50] | Returns an enumerator that iterates through the set. | | [Include][51] | Specifies the related objects to include in the query results. | | [IncludeMany][52] | Specifies which collections to include in the query results. | | [LongCount()][53] | Returns an [Int64][54] that represents the total number of elements in the set. | | [LongCount(OperatorStringHandler)][55] | Returns an [Int64][54] that represents how many elements in the set satisfy a condition. | | [LongCount(String)][56] | Returns an [Int64][54] that represents how many elements in the set satisfy a condition. | | [LongCountAsync(CancellationToken)][57] | Returns an [Int64][54] that represents the total number of elements in the set. | | [LongCountAsync(OperatorStringHandler, CancellationToken)][58] | Returns an [Int64][54] that represents how many elements in the set satisfy a condition. | | [LongCountAsync(String, CancellationToken)][59] | Returns an [Int64][54] that represents how many elements in the set satisfy a condition. | | [OrderBy(OperatorStringHandler)][60] | Sorts the elements of the set according to the *columnList*. | | [OrderBy(String)][61] | Sorts the elements of the set according to the *columnList*. | | [Select(OperatorStringHandler)][62] | Projects each element of the set into a new form. | | [Select(String)][63] | Projects each element of the set into a new form. | | [Select(OperatorStringHandler, Type)][64] | Projects each element of the set into a new form. | | [Select(String, Type)][65] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler)][66] | Projects each element of the set into a new form. | | [Select<TResult>(String)][67] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][68] | Projects each element of the set into a new form. | | [Select<TResult>(String, Func<DbDataReader, TResult>)][69] | Projects each element of the set into a new form. | | [Single()][70] | The single element of the set. | | [Single(OperatorStringHandler)][71] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [Single(String)][72] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [SingleAsync(CancellationToken)][73] | The single element of the set. | | [SingleAsync(OperatorStringHandler, CancellationToken)][74] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [SingleAsync(String, CancellationToken)][75] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [SingleOrDefault()][76] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefault(OperatorStringHandler)][77] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefault(String)][78] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefaultAsync(CancellationToken)][79] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefaultAsync(OperatorStringHandler, CancellationToken)][80] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefaultAsync(String, CancellationToken)][81] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [Skip][82] | Bypasses a specified number of elements in the set and then returns the remaining elements. | | [Take][83] | Returns a specified number of contiguous elements from the start of the set. | | [ToArray][84] | Creates an array from the set. | | [ToArrayAsync][85] | Creates an array from the set. | | [ToList][86] | Creates a [List<T>][87] from the set. | | [ToListAsync][88] | Creates a [List<T>][87] from the set. | | [ToString][89] | Returns the SQL query of the set.
(Overrides [Object.ToString()][90]) | | [Where(OperatorStringHandler)][91] | Filters the set based on a predicate. | | [Where(String)][92] | Filters the set based on a predicate. | Remarks ------- For information on how to use SqlSet see [SqlSet Tutorial][93]. See Also -------- #### Reference [DbExtensions Namespace][6] [1]: ../Database/From.md [2]: ../Database/FromQuery.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: ../SqlSet_1/README.md [5]: ../SqlTable/README.md [6]: ../README.md [7]: Database.md [8]: ../Database/README.md [9]: ResultType.md [10]: All.md [11]: All_1.md [12]: AllAsync.md [13]: AllAsync_1.md [14]: Any.md [15]: Any_1.md [16]: Any_2.md [17]: AnyAsync_2.md [18]: AnyAsync.md [19]: AnyAsync_1.md [20]: AsAsyncEnumerable.md [21]: AsEnumerable.md [22]: Cast.md [23]: Cast__1.md [24]: Contains.md [25]: ContainsAsync.md [26]: ContainsKey.md [27]: ContainsKeyAsync.md [28]: Count.md [29]: Count_1.md [30]: Count_2.md [31]: CountAsync_2.md [32]: CountAsync.md [33]: CountAsync_1.md [34]: Find.md [35]: FindAsync.md [36]: First.md [37]: First_1.md [38]: First_2.md [39]: FirstAsync_2.md [40]: FirstAsync.md [41]: FirstAsync_1.md [42]: FirstOrDefault.md [43]: FirstOrDefault_1.md [44]: FirstOrDefault_2.md [45]: FirstOrDefaultAsync_2.md [46]: FirstOrDefaultAsync.md [47]: FirstOrDefaultAsync_1.md [48]: GetAsyncEnumerator.md [49]: GetDefiningQuery.md [50]: GetEnumerator.md [51]: Include.md [52]: IncludeMany.md [53]: LongCount.md [54]: https://learn.microsoft.com/dotnet/api/system.int64 [55]: LongCount_1.md [56]: LongCount_2.md [57]: LongCountAsync_2.md [58]: LongCountAsync.md [59]: LongCountAsync_1.md [60]: OrderBy.md [61]: OrderBy_1.md [62]: Select.md [63]: Select_2.md [64]: Select_1.md [65]: Select_3.md [66]: Select__1.md [67]: Select__1_2.md [68]: Select__1_1.md [69]: Select__1_3.md [70]: Single.md [71]: Single_1.md [72]: Single_2.md [73]: SingleAsync_2.md [74]: SingleAsync.md [75]: SingleAsync_1.md [76]: SingleOrDefault.md [77]: SingleOrDefault_1.md [78]: SingleOrDefault_2.md [79]: SingleOrDefaultAsync_2.md [80]: SingleOrDefaultAsync.md [81]: SingleOrDefaultAsync_1.md [82]: Skip.md [83]: Take.md [84]: ToArray.md [85]: ToArrayAsync.md [86]: ToList.md [87]: https://learn.microsoft.com/dotnet/api/system.collections.generic.list-1 [88]: ToListAsync.md [89]: ToString.md [90]: https://learn.microsoft.com/dotnet/api/system.object.tostring [91]: Where.md [92]: Where_1.md [93]: https://maxtoroq.github.io/DbExtensions/docs/7/SqlSet.html ================================================ FILE: docs/api/DbExtensions/SqlSet/ResultType.md ================================================ SqlSet.ResultType Property ========================== The type of objects this set returns. This property can be null. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public Type? ResultType { get; } ``` #### Property Value [Type][2] See Also -------- #### Reference [SqlSet Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.type [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Select.md ================================================ SqlSet.Select(SqlSet.OperatorStringHandler) Method ================================================== Projects each element of the set into a new form. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------------------ | ------------------------------------------------- | | **Select(OperatorStringHandler)** | Projects each element of the set into a new form. | | [Select(String)][2] | Projects each element of the set into a new form. | | [Select(OperatorStringHandler, Type)][3] | Projects each element of the set into a new form. | | [Select(String, Type)][4] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler)][5] | Projects each element of the set into a new form. | | [Select<TResult>(String)][6] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][7] | Projects each element of the set into a new form. | | [Select<TResult>(String, Func<DbDataReader, TResult>)][8] | Projects each element of the set into a new form. | Syntax ------ ```csharp public SqlSet Select( ref OperatorStringHandler columnList ) ``` #### Parameters ##### *columnList*  OperatorStringHandler The list of columns to select. #### Return Value [SqlSet][9] A new [SqlSet][9]. See Also -------- #### Reference [SqlSet Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: Select_2.md [3]: Select_1.md [4]: Select_3.md [5]: Select__1.md [6]: Select__1_2.md [7]: Select__1_1.md [8]: Select__1_3.md [9]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Select_1.md ================================================ SqlSet.Select(SqlSet.OperatorStringHandler, Type) Method ======================================================== Projects each element of the set into a new form. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------------------ | ------------------------------------------------- | | [Select(OperatorStringHandler)][2] | Projects each element of the set into a new form. | | [Select(String)][3] | Projects each element of the set into a new form. | | **Select(OperatorStringHandler, Type)** | Projects each element of the set into a new form. | | [Select(String, Type)][4] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler)][5] | Projects each element of the set into a new form. | | [Select<TResult>(String)][6] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][7] | Projects each element of the set into a new form. | | [Select<TResult>(String, Func<DbDataReader, TResult>)][8] | Projects each element of the set into a new form. | Syntax ------ ```csharp public SqlSet Select( ref OperatorStringHandler columnList, Type resultType ) ``` #### Parameters ##### *columnList*  OperatorStringHandler The list of columns that maps to properties on *resultType*. ##### *resultType*  [Type][9] The type that *columnList* maps to. #### Return Value [SqlSet][10] A new [SqlSet][10]. See Also -------- #### Reference [SqlSet Class][10] [DbExtensions Namespace][1] [1]: ../README.md [2]: Select.md [3]: Select_2.md [4]: Select_3.md [5]: Select__1.md [6]: Select__1_2.md [7]: Select__1_1.md [8]: Select__1_3.md [9]: https://learn.microsoft.com/dotnet/api/system.type [10]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Select_2.md ================================================ SqlSet.Select(String) Method ============================ Projects each element of the set into a new form. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------------------ | ------------------------------------------------- | | [Select(OperatorStringHandler)][2] | Projects each element of the set into a new form. | | **Select(String)** | Projects each element of the set into a new form. | | [Select(OperatorStringHandler, Type)][3] | Projects each element of the set into a new form. | | [Select(String, Type)][4] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler)][5] | Projects each element of the set into a new form. | | [Select<TResult>(String)][6] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][7] | Projects each element of the set into a new form. | | [Select<TResult>(String, Func<DbDataReader, TResult>)][8] | Projects each element of the set into a new form. | Syntax ------ ```csharp public SqlSet Select( string columnList ) ``` #### Parameters ##### *columnList*  [String][9] The list of columns to select. #### Return Value [SqlSet][10] A new [SqlSet][10]. See Also -------- #### Reference [SqlSet Class][10] [DbExtensions Namespace][1] [1]: ../README.md [2]: Select.md [3]: Select_1.md [4]: Select_3.md [5]: Select__1.md [6]: Select__1_2.md [7]: Select__1_1.md [8]: Select__1_3.md [9]: https://learn.microsoft.com/dotnet/api/system.string [10]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Select_3.md ================================================ SqlSet.Select(String, Type) Method ================================== Projects each element of the set into a new form. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------------------ | ------------------------------------------------- | | [Select(OperatorStringHandler)][2] | Projects each element of the set into a new form. | | [Select(String)][3] | Projects each element of the set into a new form. | | [Select(OperatorStringHandler, Type)][4] | Projects each element of the set into a new form. | | **Select(String, Type)** | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler)][5] | Projects each element of the set into a new form. | | [Select<TResult>(String)][6] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][7] | Projects each element of the set into a new form. | | [Select<TResult>(String, Func<DbDataReader, TResult>)][8] | Projects each element of the set into a new form. | Syntax ------ ```csharp public SqlSet Select( string columnList, Type resultType ) ``` #### Parameters ##### *columnList*  [String][9] The list of columns that maps to properties on *resultType*. ##### *resultType*  [Type][10] The type that *columnList* maps to. #### Return Value [SqlSet][11] A new [SqlSet][11]. See Also -------- #### Reference [SqlSet Class][11] [DbExtensions Namespace][1] [1]: ../README.md [2]: Select.md [3]: Select_2.md [4]: Select_1.md [5]: Select__1.md [6]: Select__1_2.md [7]: Select__1_1.md [8]: Select__1_3.md [9]: https://learn.microsoft.com/dotnet/api/system.string [10]: https://learn.microsoft.com/dotnet/api/system.type [11]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Select__1.md ================================================ SqlSet.Select<TResult>(SqlSet.OperatorStringHandler) Method ============================================================== Projects each element of the set into a new form. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------------------ | ------------------------------------------------- | | [Select(OperatorStringHandler)][2] | Projects each element of the set into a new form. | | [Select(String)][3] | Projects each element of the set into a new form. | | [Select(OperatorStringHandler, Type)][4] | Projects each element of the set into a new form. | | [Select(String, Type)][5] | Projects each element of the set into a new form. | | **Select<TResult>(OperatorStringHandler)** | Projects each element of the set into a new form. | | [Select<TResult>(String)][6] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][7] | Projects each element of the set into a new form. | | [Select<TResult>(String, Func<DbDataReader, TResult>)][8] | Projects each element of the set into a new form. | Syntax ------ ```csharp public SqlSet Select( ref OperatorStringHandler columnList ) ``` #### Parameters ##### *columnList*  OperatorStringHandler The list of columns that maps to properties on TResult. #### Type Parameters ##### *TResult* The type that *columnList* maps to. #### Return Value [SqlSet][9]<**TResult**> A new [SqlSet<TResult>][9]. See Also -------- #### Reference [SqlSet Class][10] [DbExtensions Namespace][1] [1]: ../README.md [2]: Select.md [3]: Select_2.md [4]: Select_1.md [5]: Select_3.md [6]: Select__1_2.md [7]: Select__1_1.md [8]: Select__1_3.md [9]: ../SqlSet_1/README.md [10]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Select__1_1.md ================================================ SqlSet.Select<TResult>(SqlSet.OperatorStringHandler, Func<DbDataReader, TResult>) Method ============================================================================================== Projects each element of the set into a new form. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------------------------------------------- | ------------------------------------------------- | | [Select(OperatorStringHandler)][2] | Projects each element of the set into a new form. | | [Select(String)][3] | Projects each element of the set into a new form. | | [Select(OperatorStringHandler, Type)][4] | Projects each element of the set into a new form. | | [Select(String, Type)][5] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler)][6] | Projects each element of the set into a new form. | | [Select<TResult>(String)][7] | Projects each element of the set into a new form. | | **Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)** | Projects each element of the set into a new form. | | [Select<TResult>(String, Func<DbDataReader, TResult>)][8] | Projects each element of the set into a new form. | Syntax ------ ```csharp public SqlSet Select( ref OperatorStringHandler columnList, Func mapper ) ``` #### Parameters ##### *columnList*  OperatorStringHandler The list of columns that are used by *mapper*. ##### *mapper*  [Func][9]<[DbDataReader][10], **TResult**> A custom mapper function that creates TResult instances from the rows in the set. #### Type Parameters ##### *TResult* The type that *mapper* returns. #### Return Value [SqlSet][11]<**TResult**> A new [SqlSet<TResult>][11]. See Also -------- #### Reference [SqlSet Class][12] [DbExtensions Namespace][1] [1]: ../README.md [2]: Select.md [3]: Select_2.md [4]: Select_1.md [5]: Select_3.md [6]: Select__1.md [7]: Select__1_2.md [8]: Select__1_3.md [9]: https://learn.microsoft.com/dotnet/api/system.func-2 [10]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [11]: ../SqlSet_1/README.md [12]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Select__1_2.md ================================================ SqlSet.Select<TResult>(String) Method ======================================== Projects each element of the set into a new form. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------------------ | ------------------------------------------------- | | [Select(OperatorStringHandler)][2] | Projects each element of the set into a new form. | | [Select(String)][3] | Projects each element of the set into a new form. | | [Select(OperatorStringHandler, Type)][4] | Projects each element of the set into a new form. | | [Select(String, Type)][5] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler)][6] | Projects each element of the set into a new form. | | **Select<TResult>(String)** | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][7] | Projects each element of the set into a new form. | | [Select<TResult>(String, Func<DbDataReader, TResult>)][8] | Projects each element of the set into a new form. | Syntax ------ ```csharp public SqlSet Select( string columnList ) ``` #### Parameters ##### *columnList*  [String][9] The list of columns that maps to properties on TResult. #### Type Parameters ##### *TResult* The type that *columnList* maps to. #### Return Value [SqlSet][10]<**TResult**> A new [SqlSet<TResult>][10]. See Also -------- #### Reference [SqlSet Class][11] [DbExtensions Namespace][1] [1]: ../README.md [2]: Select.md [3]: Select_2.md [4]: Select_1.md [5]: Select_3.md [6]: Select__1.md [7]: Select__1_1.md [8]: Select__1_3.md [9]: https://learn.microsoft.com/dotnet/api/system.string [10]: ../SqlSet_1/README.md [11]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Select__1_3.md ================================================ SqlSet.Select<TResult>(String, Func<DbDataReader, TResult>) Method ======================================================================== Projects each element of the set into a new form. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------------------ | ------------------------------------------------- | | [Select(OperatorStringHandler)][2] | Projects each element of the set into a new form. | | [Select(String)][3] | Projects each element of the set into a new form. | | [Select(OperatorStringHandler, Type)][4] | Projects each element of the set into a new form. | | [Select(String, Type)][5] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler)][6] | Projects each element of the set into a new form. | | [Select<TResult>(String)][7] | Projects each element of the set into a new form. | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][8] | Projects each element of the set into a new form. | | **Select<TResult>(String, Func<DbDataReader, TResult>)** | Projects each element of the set into a new form. | Syntax ------ ```csharp public SqlSet Select( string columnList, Func mapper ) ``` #### Parameters ##### *columnList*  [String][9] The list of columns that are used by *mapper*. ##### *mapper*  [Func][10]<[DbDataReader][11], **TResult**> A custom mapper function that creates TResult instances from the rows in the set. #### Type Parameters ##### *TResult* The type that *mapper* returns. #### Return Value [SqlSet][12]<**TResult**> A new [SqlSet<TResult>][12]. See Also -------- #### Reference [SqlSet Class][13] [DbExtensions Namespace][1] [1]: ../README.md [2]: Select.md [3]: Select_2.md [4]: Select_1.md [5]: Select_3.md [6]: Select__1.md [7]: Select__1_2.md [8]: Select__1_1.md [9]: https://learn.microsoft.com/dotnet/api/system.string [10]: https://learn.microsoft.com/dotnet/api/system.func-2 [11]: https://learn.microsoft.com/dotnet/api/system.data.common.dbdatareader [12]: ../SqlSet_1/README.md [13]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Single.md ================================================ SqlSet.Single Method ==================== The single element of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | **Single()** | The single element of the set. | | [Single(OperatorStringHandler)][2] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [Single(String)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public Object Single() ``` #### Return Value [Object][4] The single element of the set. Exceptions ---------- | Exception | Condition | | ------------------------------ | ------------------------------------------------------------ | | [InvalidOperationException][5] | The set contains more than one element.-or-The set is empty. | See Also -------- #### Reference [SqlSet Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: Single_1.md [3]: Single_2.md [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/SingleAsync.md ================================================ SqlSet.SingleAsync(SqlSet.OperatorStringHandler, CancellationToken) Method ========================================================================== Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | [SingleAsync(CancellationToken)][2] | The single element of the set. | | **SingleAsync(OperatorStringHandler, CancellationToken)** | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [SingleAsync(String, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public ValueTask SingleAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Object][7]> The single element of the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | [InvalidOperationException][8] | No element satisfies the condition in *predicate*.-or-More than one element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleAsync_2.md [3]: SingleAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.object [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [9]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/SingleAsync_1.md ================================================ SqlSet.SingleAsync(String, CancellationToken) Method ==================================================== Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | [SingleAsync(CancellationToken)][2] | The single element of the set. | | [SingleAsync(OperatorStringHandler, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | **SingleAsync(String, CancellationToken)** | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public ValueTask SingleAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[Object][8]> The single element of the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | [InvalidOperationException][9] | No element satisfies the condition in *predicate*.-or-More than one element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet Class][10] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleAsync_2.md [3]: SingleAsync.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: https://learn.microsoft.com/dotnet/api/system.object [9]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [10]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/SingleAsync_2.md ================================================ SqlSet.SingleAsync(CancellationToken) Method ============================================ The single element of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | **SingleAsync(CancellationToken)** | The single element of the set. | | [SingleAsync(OperatorStringHandler, CancellationToken)][2] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [SingleAsync(String, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public ValueTask SingleAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Object][7]> The single element of the set. Exceptions ---------- | Exception | Condition | | ------------------------------ | ------------------------------------------------------------ | | [InvalidOperationException][8] | The set contains more than one element.-or-The set is empty. | See Also -------- #### Reference [SqlSet Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleAsync.md [3]: SingleAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.object [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [9]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/SingleOrDefault.md ================================================ SqlSet.SingleOrDefault Method ============================= Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **SingleOrDefault()** | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefault(OperatorStringHandler)][2] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefault(String)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public Object? SingleOrDefault() ``` #### Return Value [Object][4] The single element of the set, or a default value if the set contains no elements. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------- | | [InvalidOperationException][5] | The set contains more than one element. | See Also -------- #### Reference [SqlSet Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefault_1.md [3]: SingleOrDefault_2.md [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/SingleOrDefaultAsync.md ================================================ SqlSet.SingleOrDefaultAsync(SqlSet.OperatorStringHandler, CancellationToken) Method =================================================================================== Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [SingleOrDefaultAsync(CancellationToken)][2] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | **SingleOrDefaultAsync(OperatorStringHandler, CancellationToken)** | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefaultAsync(String, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public ValueTask SingleOrDefaultAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Object][7]> The single element of the set that satisfies the condition, or a default value if no such element is found. See Also -------- #### Reference [SqlSet Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefaultAsync_2.md [3]: SingleOrDefaultAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.object [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/SingleOrDefaultAsync_1.md ================================================ SqlSet.SingleOrDefaultAsync(String, CancellationToken) Method ============================================================= Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [SingleOrDefaultAsync(CancellationToken)][2] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefaultAsync(OperatorStringHandler, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | **SingleOrDefaultAsync(String, CancellationToken)** | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public ValueTask SingleOrDefaultAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[Object][8]> The single element of the set that satisfies the condition, or a default value if no such element is found. See Also -------- #### Reference [SqlSet Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefaultAsync_2.md [3]: SingleOrDefaultAsync.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: https://learn.microsoft.com/dotnet/api/system.object [9]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/SingleOrDefaultAsync_2.md ================================================ SqlSet.SingleOrDefaultAsync(CancellationToken) Method ===================================================== Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **SingleOrDefaultAsync(CancellationToken)** | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefaultAsync(OperatorStringHandler, CancellationToken)][2] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefaultAsync(String, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public ValueTask SingleOrDefaultAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Object][7]> The single element of the set, or a default value if the set contains no elements. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------- | | [InvalidOperationException][8] | The set contains more than one element. | See Also -------- #### Reference [SqlSet Class][9] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefaultAsync.md [3]: SingleOrDefaultAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.object [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [9]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/SingleOrDefault_1.md ================================================ SqlSet.SingleOrDefault(SqlSet.OperatorStringHandler) Method =========================================================== Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [SingleOrDefault()][2] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | **SingleOrDefault(OperatorStringHandler)** | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefault(String)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public Object? SingleOrDefault( ref OperatorStringHandler? predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [Object][4] The single element of the set that satisfies the condition, or a default value if no such element is found. See Also -------- #### Reference [SqlSet Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefault.md [3]: SingleOrDefault_2.md [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/SingleOrDefault_2.md ================================================ SqlSet.SingleOrDefault(String) Method ===================================== Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [SingleOrDefault()][2] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefault(OperatorStringHandler)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | **SingleOrDefault(String)** | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public Object? SingleOrDefault( string predicate ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. #### Return Value [Object][5] The single element of the set that satisfies the condition, or a default value if no such element is found. See Also -------- #### Reference [SqlSet Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefault.md [3]: SingleOrDefault_1.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.object [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Single_1.md ================================================ SqlSet.Single(SqlSet.OperatorStringHandler) Method ================================================== Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | [Single()][2] | The single element of the set. | | **Single(OperatorStringHandler)** | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [Single(String)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public Object Single( ref OperatorStringHandler predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [Object][4] The single element of the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | [InvalidOperationException][5] | No element satisfies the condition in *predicate*.-or-More than one element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: Single.md [3]: Single_2.md [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Single_2.md ================================================ SqlSet.Single(String) Method ============================ Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | [Single()][2] | The single element of the set. | | [Single(OperatorStringHandler)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | **Single(String)** | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public Object Single( string predicate ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. #### Return Value [Object][5] The single element of the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | [InvalidOperationException][6] | No element satisfies the condition in *predicate*.-or-More than one element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: Single.md [3]: Single_1.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.object [6]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Skip.md ================================================ SqlSet.Skip Method ================== Bypasses a specified number of elements in the set and then returns the remaining elements. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlSet Skip( int count ) ``` #### Parameters ##### *count*  [Int32][2] The number of elements to skip before returning the remaining elements. #### Return Value [SqlSet][3] A new [SqlSet][3] that contains the elements that occur after the specified index in the current set. See Also -------- #### Reference [SqlSet Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.int32 [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Take.md ================================================ SqlSet.Take Method ================== Returns a specified number of contiguous elements from the start of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlSet Take( int count ) ``` #### Parameters ##### *count*  [Int32][2] The number of elements to return. #### Return Value [SqlSet][3] A new [SqlSet][3] that contains the specified number of elements from the start of the current set. See Also -------- #### Reference [SqlSet Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.int32 [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/ToArray.md ================================================ SqlSet.ToArray Method ===================== Creates an array from the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public Object[] ToArray() ``` #### Return Value [Object][2][] An array that contains the elements from the set. See Also -------- #### Reference [SqlSet Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/ToArrayAsync.md ================================================ SqlSet.ToArrayAsync Method ========================== Creates an array from the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask ToArrayAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][2]  (Optional) The [CancellationToken][2] to monitor for cancellation requests. The default is [None][3]. #### Return Value [ValueTask][4]<[Object][5][]> An array that contains the elements from the set. See Also -------- #### Reference [SqlSet Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [4]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [5]: https://learn.microsoft.com/dotnet/api/system.object [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/ToList.md ================================================ SqlSet.ToList Method ==================== Creates a [List<T>][1] from the set. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public List ToList() ``` #### Return Value [List][1]<[Object][3]> A [List<T>][1] that contains elements from the set. See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.collections.generic.list-1 [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/ToListAsync.md ================================================ SqlSet.ToListAsync Method ========================= Creates a [List<T>][1] from the set. **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask> ToListAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[List][1]<[Object][6]>> A [List<T>][1] that contains elements from the set. See Also -------- #### Reference [SqlSet Class][7] [DbExtensions Namespace][2] [1]: https://learn.microsoft.com/dotnet/api/system.collections.generic.list-1 [2]: ../README.md [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.object [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/ToString.md ================================================ SqlSet.ToString Method ====================== Returns the SQL query of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public override string ToString() ``` #### Return Value [String][2] The SQL query of the set. See Also -------- #### Reference [SqlSet Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Where.md ================================================ SqlSet.Where(SqlSet.OperatorStringHandler) Method ================================================= Filters the set based on a predicate. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------- | ------------------------------------- | | **Where(OperatorStringHandler)** | Filters the set based on a predicate. | | [Where(String)][2] | Filters the set based on a predicate. | Syntax ------ ```csharp public SqlSet Where( ref OperatorStringHandler predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [SqlSet][3] A new [SqlSet][3] that contains elements from the current set that satisfy the condition. See Also -------- #### Reference [SqlSet Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: Where_1.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet/Where_1.md ================================================ SqlSet.Where(String) Method =========================== Filters the set based on a predicate. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------- | ------------------------------------- | | [Where(OperatorStringHandler)][2] | Filters the set based on a predicate. | | **Where(String)** | Filters the set based on a predicate. | Syntax ------ ```csharp public SqlSet Where( string predicate ) ``` #### Parameters ##### *predicate*  [String][3] A SQL expression to test each row for a condition. #### Return Value [SqlSet][4] A new [SqlSet][4] that contains elements from the current set that satisfy the condition. See Also -------- #### Reference [SqlSet Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: Where.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/AsAsyncEnumerable.md ================================================ SqlSet<TResult>.AsAsyncEnumerable Method =========================================== Gets all TResult objects in the set. The query is deferred-executed. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public IAsyncEnumerable AsAsyncEnumerable() ``` #### Return Value [IAsyncEnumerable][2]<[TResult][3]> All TResult objects in the set. See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerable-1 [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/AsEnumerable.md ================================================ SqlSet<TResult>.AsEnumerable Method ====================================== Gets all TResult objects in the set. The query is deferred-executed. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public IEnumerable AsEnumerable() ``` #### Return Value [IEnumerable][2]<[TResult][3]> All TResult objects in the set. See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Contains.md ================================================ SqlSet<TResult>.Contains(TResult) Method =========================================== Checks the existance of the *entity*, using the primary key value. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------- | ------------------------------------------------------------------ | | [Contains(Object)][2] | Checks the existance of the *entity*, using the primary key value. | | **Contains(TResult)** | Checks the existance of the *entity*, using the primary key value. | Syntax ------ ```csharp public bool Contains( TResult entity ) ``` #### Parameters ##### *entity*  [TResult][3] The entity whose existance is to be checked. #### Return Value [Boolean][4] `true` if the primary key value exists in the database; otherwise, `false`. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][5] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: ../SqlSet/Contains.md [3]: README.md [4]: https://learn.microsoft.com/dotnet/api/system.boolean [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/ContainsAsync.md ================================================ SqlSet<TResult>.ContainsAsync(TResult, CancellationToken) Method =================================================================== Checks the existance of the *entity*, using the primary key value. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------- | ------------------------------------------------------------------ | | [ContainsAsync(Object, CancellationToken)][2] | Checks the existance of the *entity*, using the primary key value. | | **ContainsAsync(TResult, CancellationToken)** | Checks the existance of the *entity*, using the primary key value. | Syntax ------ ```csharp public ValueTask ContainsAsync( TResult entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [TResult][3] The entity whose existance is to be checked. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[Boolean][7]> `true` if the primary key value exists in the database; otherwise, `false`. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][8] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: ../SqlSet/ContainsAsync.md [3]: README.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: https://learn.microsoft.com/dotnet/api/system.boolean [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Find.md ================================================ SqlSet<TResult>.Find Method ============================== Gets the entity whose primary key matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public TResult Find( Object id ) ``` #### Parameters ##### *id*  [Object][2] The primary key value. #### Return Value [TResult][3] The entity whose primary key matches the *id* parameter, or null if the *id* does not exist. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][4] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: README.md [4]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/FindAsync.md ================================================ SqlSet<TResult>.FindAsync Method =================================== Gets the entity whose primary key matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask FindAsync( Object id, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *id*  [Object][2] The primary key value. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[TResult][6]> The entity whose primary key matches the *id* parameter, or null if the *id* does not exist. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][7] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet<TResult> Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: README.md [7]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/First.md ================================================ SqlSet<TResult>.First Method =============================== Returns the first element of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------- | -------------------------------------------------------------------------- | | **First()** | Returns the first element of the set. | | [First(OperatorStringHandler)][2] | Returns the first element in the set that satisfies a specified condition. | | [First(String)][3] | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public TResult First() ``` #### Return Value [TResult][4] The first element in the set. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------- | | [InvalidOperationException][5] | The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: First_1.md [3]: First_2.md [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/FirstAsync.md ================================================ SqlSet<TResult>.FirstAsync(SqlSet.OperatorStringHandler, CancellationToken) Method ===================================================================================== Returns the first element in the set that satisfies a specified condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------------- | -------------------------------------------------------------------------- | | [FirstAsync(CancellationToken)][2] | Returns the first element of the set. | | **FirstAsync(OperatorStringHandler, CancellationToken)** | Returns the first element in the set that satisfies a specified condition. | | [FirstAsync(String, CancellationToken)][3] | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public ValueTask FirstAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[TResult][7]> The first element in the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------------------------------------------------------------- | | [InvalidOperationException][8] | No element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstAsync_2.md [3]: FirstAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: README.md [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/FirstAsync_1.md ================================================ SqlSet<TResult>.FirstAsync(String, CancellationToken) Method =============================================================== Returns the first element in the set that satisfies a specified condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------- | -------------------------------------------------------------------------- | | [FirstAsync(CancellationToken)][2] | Returns the first element of the set. | | [FirstAsync(OperatorStringHandler, CancellationToken)][3] | Returns the first element in the set that satisfies a specified condition. | | **FirstAsync(String, CancellationToken)** | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public ValueTask FirstAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[TResult][8]> The first element in the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------------------------------------------------------------- | | [InvalidOperationException][9] | No element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstAsync_2.md [3]: FirstAsync.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: README.md [9]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/FirstAsync_2.md ================================================ SqlSet<TResult>.FirstAsync(CancellationToken) Method ======================================================= Returns the first element of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------- | -------------------------------------------------------------------------- | | **FirstAsync(CancellationToken)** | Returns the first element of the set. | | [FirstAsync(OperatorStringHandler, CancellationToken)][2] | Returns the first element in the set that satisfies a specified condition. | | [FirstAsync(String, CancellationToken)][3] | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public ValueTask FirstAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[TResult][7]> The first element in the set. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------- | | [InvalidOperationException][8] | The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstAsync.md [3]: FirstAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: README.md [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/FirstOrDefault.md ================================================ SqlSet<TResult>.FirstOrDefault Method ======================================== Returns the first element of the set, or a default value if the set contains no elements. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | **FirstOrDefault()** | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefault(OperatorStringHandler)][2] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefault(String)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public TResult FirstOrDefault() ``` #### Return Value [TResult][4] A default value if the set is empty; otherwise, the first element. See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefault_1.md [3]: FirstOrDefault_2.md [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/FirstOrDefaultAsync.md ================================================ SqlSet<TResult>.FirstOrDefaultAsync(SqlSet.OperatorStringHandler, CancellationToken) Method ============================================================================================== Returns the first element of the set that satisfies a condition or a default value if no such element is found. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | [FirstOrDefaultAsync(CancellationToken)][2] | Returns the first element of the set, or a default value if the set contains no elements. | | **FirstOrDefaultAsync(OperatorStringHandler, CancellationToken)** | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefaultAsync(String, CancellationToken)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public ValueTask FirstOrDefaultAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[TResult][7]> A default value if the set is empty or if no element passes the test specified by *predicate*; otherwise, the first element that passes the test specified by *predicate*. See Also -------- #### Reference [SqlSet<TResult> Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefaultAsync_2.md [3]: FirstOrDefaultAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/FirstOrDefaultAsync_1.md ================================================ SqlSet<TResult>.FirstOrDefaultAsync(String, CancellationToken) Method ======================================================================== Returns the first element of the set that satisfies a condition or a default value if no such element is found. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | [FirstOrDefaultAsync(CancellationToken)][2] | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefaultAsync(OperatorStringHandler, CancellationToken)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | **FirstOrDefaultAsync(String, CancellationToken)** | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public ValueTask FirstOrDefaultAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[TResult][8]> A default value if the set is empty or if no element passes the test specified by *predicate*; otherwise, the first element that passes the test specified by *predicate*. See Also -------- #### Reference [SqlSet<TResult> Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefaultAsync_2.md [3]: FirstOrDefaultAsync.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/FirstOrDefaultAsync_2.md ================================================ SqlSet<TResult>.FirstOrDefaultAsync(CancellationToken) Method ================================================================ Returns the first element of the set, or a default value if the set contains no elements. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | **FirstOrDefaultAsync(CancellationToken)** | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefaultAsync(OperatorStringHandler, CancellationToken)][2] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefaultAsync(String, CancellationToken)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public ValueTask FirstOrDefaultAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[TResult][7]> A default value if the set is empty; otherwise, the first element. See Also -------- #### Reference [SqlSet<TResult> Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefaultAsync.md [3]: FirstOrDefaultAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/FirstOrDefault_1.md ================================================ SqlSet<TResult>.FirstOrDefault(SqlSet.OperatorStringHandler) Method ====================================================================== Returns the first element of the set that satisfies a condition or a default value if no such element is found. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | [FirstOrDefault()][2] | Returns the first element of the set, or a default value if the set contains no elements. | | **FirstOrDefault(OperatorStringHandler)** | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefault(String)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public TResult FirstOrDefault( ref OperatorStringHandler? predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [TResult][4] A default value if the set is empty or if no element passes the test specified by *predicate*; otherwise, the first element that passes the test specified by *predicate*. See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefault.md [3]: FirstOrDefault_2.md [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/FirstOrDefault_2.md ================================================ SqlSet<TResult>.FirstOrDefault(String) Method ================================================ Returns the first element of the set that satisfies a condition or a default value if no such element is found. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | | [FirstOrDefault()][2] | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefault(OperatorStringHandler)][3] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | **FirstOrDefault(String)** | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | Syntax ------ ```csharp public TResult FirstOrDefault( string predicate ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. #### Return Value [TResult][5] A default value if the set is empty or if no element passes the test specified by *predicate*; otherwise, the first element that passes the test specified by *predicate*. See Also -------- #### Reference [SqlSet<TResult> Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: FirstOrDefault.md [3]: FirstOrDefault_1.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/First_1.md ================================================ SqlSet<TResult>.First(SqlSet.OperatorStringHandler) Method ============================================================= Returns the first element in the set that satisfies a specified condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------- | -------------------------------------------------------------------------- | | [First()][2] | Returns the first element of the set. | | **First(OperatorStringHandler)** | Returns the first element in the set that satisfies a specified condition. | | [First(String)][3] | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public TResult First( ref OperatorStringHandler predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [TResult][4] The first element in the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------------------------------------------------------------- | | [InvalidOperationException][5] | No element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: First.md [3]: First_2.md [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/First_2.md ================================================ SqlSet<TResult>.First(String) Method ======================================= Returns the first element in the set that satisfies a specified condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------- | -------------------------------------------------------------------------- | | [First()][2] | Returns the first element of the set. | | [First(OperatorStringHandler)][3] | Returns the first element in the set that satisfies a specified condition. | | **First(String)** | Returns the first element in the set that satisfies a specified condition. | Syntax ------ ```csharp public TResult First( string predicate ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. #### Return Value [TResult][5] The first element in the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------------------------------------------------------------- | | [InvalidOperationException][6] | No element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: First.md [3]: First_1.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: README.md [6]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/GetAsyncEnumerator.md ================================================ SqlSet<TResult>.GetAsyncEnumerator Method ============================================ Returns an async enumerator that iterates through the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public IAsyncEnumerator GetAsyncEnumerator( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][2]  (Optional) The [CancellationToken][2] to monitor for cancellation requests. The default is [None][3]. #### Return Value [IAsyncEnumerator][4]<[TResult][5]> A [IAsyncEnumerator<T>][4] for the set. See Also -------- #### Reference [SqlSet<TResult> Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [4]: https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerator-1 [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/GetEnumerator.md ================================================ SqlSet<TResult>.GetEnumerator Method ======================================= Returns an enumerator that iterates through the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public IEnumerator GetEnumerator() ``` #### Return Value [IEnumerator][2]<[TResult][3]> A [IEnumerator<T>][2] for the set. See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerator-1 [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Include.md ================================================ SqlSet<TResult>.Include(Func<TResult, Object>, String) Method =================================================================== Specifies the related objects to include in the query results. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------- | -------------------------------------------------------------- | | [Include(String)][2] | Specifies the related objects to include in the query results. | | **Include(Func<TResult, Object>, String)** | Specifies the related objects to include in the query results. | Syntax ------ ```csharp public SqlSet Include( Func path, string pathExpr = "" ) ``` #### Parameters ##### *path*  [Func][3]<[TResult][4], [Object][5]> Lambda expression that returns the deepest related object to return in the query results. ##### *pathExpr*  [String][6]  (Optional) This argument is compiler generated. #### Return Value [SqlSet][4]<[TResult][4]> A new [SqlSet<TResult>][4] with the defined query path. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][7] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: Include_1.md [3]: https://learn.microsoft.com/dotnet/api/system.func-2 [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.object [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/IncludeMany.md ================================================ SqlSet<TResult>.IncludeMany(String, Func<SqlSet, SqlSet>) Method ====================================================================== Specifies which collections to include in the query results. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ | | **IncludeMany(String, Func<SqlSet, SqlSet>)** | Specifies which collections to include in the query results. | | [IncludeMany<TElement>(Func<TResult, ICollection<TElement>>, Func<SqlSet<TElement>, SqlSet<TElement>>, String)][2] | Specifies which collections to include in the query results. | Syntax ------ ```csharp public SqlSet IncludeMany( string path, Func? manySetup = null ) ``` #### Parameters ##### *path*  [String][3] Dot-separated list of one or more related objects that ends with the collection to load. ##### *manySetup*  [Func][4]<[SqlSet][5], [SqlSet][5]>  (Optional) A function to customize how the collection is loaded. #### Return Value [SqlSet][6]<[TResult][6]> A new [SqlSet<TResult>][6]. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][7] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet<TResult> Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: IncludeMany__1.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: https://learn.microsoft.com/dotnet/api/system.func-2 [5]: ../SqlSet/README.md [6]: README.md [7]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/IncludeMany__1.md ================================================ SqlSet<TResult>.IncludeMany<TElement>(Func<TResult, ICollection<TElement>>, Func<SqlSet<TElement>, SqlSet<TElement>>, String) Method ========================================================================================================================================================= Specifies which collections to include in the query results. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | | [IncludeMany(String, Func<SqlSet, SqlSet>)][2] | Specifies which collections to include in the query results. | | **IncludeMany<TElement>(Func<TResult, ICollection<TElement>>, Func<SqlSet<TElement>, SqlSet<TElement>>, String)** | Specifies which collections to include in the query results. | Syntax ------ ```csharp public SqlSet IncludeMany( Func?> path, Func, SqlSet>? manySetup = null, string pathExpr = "" ) ``` #### Parameters ##### *path*  [Func][3]<[TResult][4], [ICollection][5]<**TElement**>> Lambda expression that returns the collection to load. ##### *manySetup*  [Func][3]<[SqlSet][4]<**TElement**>, [SqlSet][4]<**TElement**>>  (Optional) A function to customize how the collection is loaded. ##### *pathExpr*  [String][6]  (Optional) This argument is compiler generated. #### Type Parameters ##### *TElement* The type of objects the collection holds. #### Return Value [SqlSet][4]<[TResult][4]> A new [SqlSet<TResult>][4]. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][7] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: IncludeMany.md [3]: https://learn.microsoft.com/dotnet/api/system.func-2 [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.collections.generic.icollection-1 [6]: https://learn.microsoft.com/dotnet/api/system.string [7]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Include_1.md ================================================ SqlSet<TResult>.Include(String) Method ========================================= Specifies the related objects to include in the query results. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------- | -------------------------------------------------------------- | | **Include(String)** | Specifies the related objects to include in the query results. | | [Include(Func<TResult, Object>, String)][2] | Specifies the related objects to include in the query results. | Syntax ------ ```csharp public SqlSet Include( string path ) ``` #### Parameters ##### *path*  [String][3] Dot-separated list of related objects to return in the query results. #### Return Value [SqlSet][4]<[TResult][4]> A new [SqlSet<TResult>][4] with the defined query path. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------------------------------------------------- | | [InvalidOperationException][5] | This method can only be used on sets where the result type is an annotated class. | See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: Include.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/OrderBy.md ================================================ SqlSet<TResult>.OrderBy(SqlSet.OperatorStringHandler) Method =============================================================== Sorts the elements of the set according to the *columnList*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------- | ------------------------------------------------------------ | | **OrderBy(OperatorStringHandler)** | Sorts the elements of the set according to the *columnList*. | | [OrderBy(String)][2] | Sorts the elements of the set according to the *columnList*. | Syntax ------ ```csharp public SqlSet OrderBy( ref OperatorStringHandler columnList ) ``` #### Parameters ##### *columnList*  OperatorStringHandler The list of columns to base the sort on. #### Return Value [SqlSet][3]<[TResult][3]> A new [SqlSet<TResult>][3] whose elements are sorted according to *columnList*. See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: OrderBy_1.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/OrderBy_1.md ================================================ SqlSet<TResult>.OrderBy(String) Method ========================================= Sorts the elements of the set according to the *columnList*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------- | ------------------------------------------------------------ | | [OrderBy(OperatorStringHandler)][2] | Sorts the elements of the set according to the *columnList*. | | **OrderBy(String)** | Sorts the elements of the set according to the *columnList*. | Syntax ------ ```csharp public SqlSet OrderBy( string columnList ) ``` #### Parameters ##### *columnList*  [String][3] The list of columns to base the sort on. #### Return Value [SqlSet][4]<[TResult][4]> A new [SqlSet<TResult>][4] whose elements are sorted according to *columnList*. See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: OrderBy.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/README.md ================================================ SqlSet<TResult> Class ======================== Represents an immutable, connected SQL query that maps to TResult objects. This class cannot be instantiated, to get an instance use one of the [Database.From<TResult>(String)][1] or [Database.FromQuery<TResult>(SqlBuilder)][2] overloads. Inheritance Hierarchy --------------------- [System.Object][3]   [DbExtensions.SqlSet][4]     **DbExtensions.SqlSet<TResult>**       [DbExtensions.SqlTable<TEntity>][5] **Namespace:** [DbExtensions][6] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public class SqlSet : SqlSet ``` #### Type Parameters ##### *TResult* The type of objects to map the results to. The **SqlSet<TResult>** type exposes the following members. Properties ---------- | Name | Description | | --------------- | -------------------------------------------------------------------------------------------------- | | [Database][7] | The [Database][8] this set is connected to.
(Inherited from [SqlSet][4]) | | [ResultType][9] | The type of objects this set returns. This property can be null.
(Inherited from [SqlSet][4]) | Methods ------- | Name | Description | | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [All(OperatorStringHandler)][10] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [All(String)][11] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [AllAsync(OperatorStringHandler, CancellationToken)][12] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [AllAsync(String, CancellationToken)][13] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [Any()][14] | Determines whether the set contains any elements.
(Inherited from [SqlSet][4]) | | [Any(OperatorStringHandler)][15] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [Any(String)][16] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [AnyAsync(CancellationToken)][17] | Determines whether the set contains any elements.
(Inherited from [SqlSet][4]) | | [AnyAsync(OperatorStringHandler, CancellationToken)][18] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [AnyAsync(String, CancellationToken)][19] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [AsAsyncEnumerable][20] | Gets all TResult objects in the set. The query is deferred-executed. | | [AsEnumerable][21] | Gets all TResult objects in the set. The query is deferred-executed. | | [Cast(Type)][22] | Casts the elements of the set to the specified type.
(Inherited from [SqlSet][4]) | | [Cast<TResult>()][23] | Casts the elements of the set to the specified type.
(Inherited from [SqlSet][4]) | | [Contains(Object)][24] | Checks the existance of the *entity*, using the primary key value.
(Inherited from [SqlSet][4]) | | [Contains(TResult)][25] | Checks the existance of the *entity*, using the primary key value. | | [ContainsAsync(Object, CancellationToken)][26] | Checks the existance of the *entity*, using the primary key value.
(Inherited from [SqlSet][4]) | | [ContainsAsync(TResult, CancellationToken)][27] | Checks the existance of the *entity*, using the primary key value. | | [ContainsKey][28] | Checks the existance of an entity whose primary matches the *id* parameter.
(Inherited from [SqlSet][4]) | | [ContainsKeyAsync][29] | Checks the existance of an entity whose primary matches the *id* parameter.
(Inherited from [SqlSet][4]) | | [Count()][30] | Returns the number of elements in the set.
(Inherited from [SqlSet][4]) | | [Count(OperatorStringHandler)][31] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [Count(String)][32] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [CountAsync(CancellationToken)][33] | Returns the number of elements in the set.
(Inherited from [SqlSet][4]) | | [CountAsync(OperatorStringHandler, CancellationToken)][34] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [CountAsync(String, CancellationToken)][35] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [Find][36] | Gets the entity whose primary key matches the *id* parameter. | | [FindAsync][37] | Gets the entity whose primary key matches the *id* parameter. | | [First()][38] | Returns the first element of the set. | | [First(OperatorStringHandler)][39] | Returns the first element in the set that satisfies a specified condition. | | [First(String)][40] | Returns the first element in the set that satisfies a specified condition. | | [FirstAsync(CancellationToken)][41] | Returns the first element of the set. | | [FirstAsync(OperatorStringHandler, CancellationToken)][42] | Returns the first element in the set that satisfies a specified condition. | | [FirstAsync(String, CancellationToken)][43] | Returns the first element in the set that satisfies a specified condition. | | [FirstOrDefault()][44] | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefault(OperatorStringHandler)][45] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefault(String)][46] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefaultAsync(CancellationToken)][47] | Returns the first element of the set, or a default value if the set contains no elements. | | [FirstOrDefaultAsync(OperatorStringHandler, CancellationToken)][48] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [FirstOrDefaultAsync(String, CancellationToken)][49] | Returns the first element of the set that satisfies a condition or a default value if no such element is found. | | [GetAsyncEnumerator][50] | Returns an async enumerator that iterates through the set. | | [GetDefiningQuery][51] | Returns the SQL query that is the source of data for the set.
(Inherited from [SqlSet][4]) | | [GetEnumerator][52] | Returns an enumerator that iterates through the set. | | [Include(String)][53] | Specifies the related objects to include in the query results. | | [Include(Func<TResult, Object>, String)][54] | Specifies the related objects to include in the query results. | | [IncludeMany(String, Func<SqlSet, SqlSet>)][55] | Specifies which collections to include in the query results. | | [IncludeMany<TElement>(Func<TResult, ICollection<TElement>>, Func<SqlSet<TElement>, SqlSet<TElement>>, String)][56] | Specifies which collections to include in the query results. | | [LongCount()][57] | Returns an [Int64][58] that represents the total number of elements in the set.
(Inherited from [SqlSet][4]) | | [LongCount(OperatorStringHandler)][59] | Returns an [Int64][58] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [LongCount(String)][60] | Returns an [Int64][58] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [LongCountAsync(CancellationToken)][61] | Returns an [Int64][58] that represents the total number of elements in the set.
(Inherited from [SqlSet][4]) | | [LongCountAsync(OperatorStringHandler, CancellationToken)][62] | Returns an [Int64][58] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [LongCountAsync(String, CancellationToken)][63] | Returns an [Int64][58] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [OrderBy(OperatorStringHandler)][64] | Sorts the elements of the set according to the *columnList*. | | [OrderBy(String)][65] | Sorts the elements of the set according to the *columnList*. | | [Select(OperatorStringHandler, Type)][66] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select(String, Type)][67] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(OperatorStringHandler)][68] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(String)][69] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][70] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(String, Func<DbDataReader, TResult>)][71] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Single()][72] | The single element of the set. | | [Single(OperatorStringHandler)][73] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [Single(String)][74] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [SingleAsync(CancellationToken)][75] | The single element of the set. | | [SingleAsync(OperatorStringHandler, CancellationToken)][76] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [SingleAsync(String, CancellationToken)][77] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [SingleOrDefault()][78] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefault(OperatorStringHandler)][79] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefault(String)][80] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefaultAsync(CancellationToken)][81] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefaultAsync(OperatorStringHandler, CancellationToken)][82] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefaultAsync(String, CancellationToken)][83] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [Skip][84] | Bypasses a specified number of elements in the set and then returns the remaining elements. | | [Take][85] | Returns a specified number of contiguous elements from the start of the set. | | [ToArray][86] | Creates an array from the set. | | [ToArrayAsync][87] | Creates an array from the set. | | [ToList][88] | Creates a List<TResult> from the set. | | [ToListAsync][89] | Creates a List<TResult> from the set. | | [ToString][90] | Returns the SQL query of the set.
(Inherited from [SqlSet][4]) | | [Where(OperatorStringHandler)][91] | Filters the set based on a predicate. | | [Where(String)][92] | Filters the set based on a predicate. | Remarks ------- For information on how to use SqlSet see [SqlSet Tutorial][93]. See Also -------- #### Reference [DbExtensions Namespace][6] [1]: ../Database/From__1.md [2]: ../Database/FromQuery__1.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: ../SqlSet/README.md [5]: ../SqlTable_1/README.md [6]: ../README.md [7]: ../SqlSet/Database.md [8]: ../Database/README.md [9]: ../SqlSet/ResultType.md [10]: ../SqlSet/All.md [11]: ../SqlSet/All_1.md [12]: ../SqlSet/AllAsync.md [13]: ../SqlSet/AllAsync_1.md [14]: ../SqlSet/Any.md [15]: ../SqlSet/Any_1.md [16]: ../SqlSet/Any_2.md [17]: ../SqlSet/AnyAsync_2.md [18]: ../SqlSet/AnyAsync.md [19]: ../SqlSet/AnyAsync_1.md [20]: AsAsyncEnumerable.md [21]: AsEnumerable.md [22]: ../SqlSet/Cast.md [23]: ../SqlSet/Cast__1.md [24]: ../SqlSet/Contains.md [25]: Contains.md [26]: ../SqlSet/ContainsAsync.md [27]: ContainsAsync.md [28]: ../SqlSet/ContainsKey.md [29]: ../SqlSet/ContainsKeyAsync.md [30]: ../SqlSet/Count.md [31]: ../SqlSet/Count_1.md [32]: ../SqlSet/Count_2.md [33]: ../SqlSet/CountAsync_2.md [34]: ../SqlSet/CountAsync.md [35]: ../SqlSet/CountAsync_1.md [36]: Find.md [37]: FindAsync.md [38]: First.md [39]: First_1.md [40]: First_2.md [41]: FirstAsync_2.md [42]: FirstAsync.md [43]: FirstAsync_1.md [44]: FirstOrDefault.md [45]: FirstOrDefault_1.md [46]: FirstOrDefault_2.md [47]: FirstOrDefaultAsync_2.md [48]: FirstOrDefaultAsync.md [49]: FirstOrDefaultAsync_1.md [50]: GetAsyncEnumerator.md [51]: ../SqlSet/GetDefiningQuery.md [52]: GetEnumerator.md [53]: Include_1.md [54]: Include.md [55]: IncludeMany.md [56]: IncludeMany__1.md [57]: ../SqlSet/LongCount.md [58]: https://learn.microsoft.com/dotnet/api/system.int64 [59]: ../SqlSet/LongCount_1.md [60]: ../SqlSet/LongCount_2.md [61]: ../SqlSet/LongCountAsync_2.md [62]: ../SqlSet/LongCountAsync.md [63]: ../SqlSet/LongCountAsync_1.md [64]: OrderBy.md [65]: OrderBy_1.md [66]: ../SqlSet/Select_1.md [67]: ../SqlSet/Select_3.md [68]: ../SqlSet/Select__1.md [69]: ../SqlSet/Select__1_2.md [70]: ../SqlSet/Select__1_1.md [71]: ../SqlSet/Select__1_3.md [72]: Single.md [73]: Single_1.md [74]: Single_2.md [75]: SingleAsync_2.md [76]: SingleAsync.md [77]: SingleAsync_1.md [78]: SingleOrDefault.md [79]: SingleOrDefault_1.md [80]: SingleOrDefault_2.md [81]: SingleOrDefaultAsync_2.md [82]: SingleOrDefaultAsync.md [83]: SingleOrDefaultAsync_1.md [84]: Skip.md [85]: Take.md [86]: ToArray.md [87]: ToArrayAsync.md [88]: ToList.md [89]: ToListAsync.md [90]: ../SqlSet/ToString.md [91]: Where.md [92]: Where_1.md [93]: https://maxtoroq.github.io/DbExtensions/docs/7/SqlSet.html ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Single.md ================================================ SqlSet<TResult>.Single Method ================================ The single element of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | **Single()** | The single element of the set. | | [Single(OperatorStringHandler)][2] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [Single(String)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public TResult Single() ``` #### Return Value [TResult][4] The single element of the set. Exceptions ---------- | Exception | Condition | | ------------------------------ | ------------------------------------------------------------ | | [InvalidOperationException][5] | The set contains more than one element.-or-The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: Single_1.md [3]: Single_2.md [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/SingleAsync.md ================================================ SqlSet<TResult>.SingleAsync(SqlSet.OperatorStringHandler, CancellationToken) Method ====================================================================================== Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | [SingleAsync(CancellationToken)][2] | The single element of the set. | | **SingleAsync(OperatorStringHandler, CancellationToken)** | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [SingleAsync(String, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public ValueTask SingleAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[TResult][7]> The single element of the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | [InvalidOperationException][8] | No element satisfies the condition in *predicate*.-or-More than one element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleAsync_2.md [3]: SingleAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: README.md [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/SingleAsync_1.md ================================================ SqlSet<TResult>.SingleAsync(String, CancellationToken) Method ================================================================ Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | [SingleAsync(CancellationToken)][2] | The single element of the set. | | [SingleAsync(OperatorStringHandler, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | **SingleAsync(String, CancellationToken)** | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public ValueTask SingleAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[TResult][8]> The single element of the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | [InvalidOperationException][9] | No element satisfies the condition in *predicate*.-or-More than one element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleAsync_2.md [3]: SingleAsync.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: README.md [9]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/SingleAsync_2.md ================================================ SqlSet<TResult>.SingleAsync(CancellationToken) Method ======================================================== The single element of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | **SingleAsync(CancellationToken)** | The single element of the set. | | [SingleAsync(OperatorStringHandler, CancellationToken)][2] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [SingleAsync(String, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public ValueTask SingleAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[TResult][7]> The single element of the set. Exceptions ---------- | Exception | Condition | | ------------------------------ | ------------------------------------------------------------ | | [InvalidOperationException][8] | The set contains more than one element.-or-The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleAsync.md [3]: SingleAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: README.md [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/SingleOrDefault.md ================================================ SqlSet<TResult>.SingleOrDefault Method ========================================= Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **SingleOrDefault()** | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefault(OperatorStringHandler)][2] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefault(String)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public TResult SingleOrDefault() ``` #### Return Value [TResult][4] The single element of the set, or a default value if the set contains no elements. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------- | | [InvalidOperationException][5] | The set contains more than one element. | See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefault_1.md [3]: SingleOrDefault_2.md [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/SingleOrDefaultAsync.md ================================================ SqlSet<TResult>.SingleOrDefaultAsync(SqlSet.OperatorStringHandler, CancellationToken) Method =============================================================================================== Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [SingleOrDefaultAsync(CancellationToken)][2] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | **SingleOrDefaultAsync(OperatorStringHandler, CancellationToken)** | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefaultAsync(String, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public ValueTask SingleOrDefaultAsync( OperatorStringHandler predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[TResult][7]> The single element of the set that satisfies the condition, or a default value if no such element is found. See Also -------- #### Reference [SqlSet<TResult> Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefaultAsync_2.md [3]: SingleOrDefaultAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/SingleOrDefaultAsync_1.md ================================================ SqlSet<TResult>.SingleOrDefaultAsync(String, CancellationToken) Method ========================================================================= Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [SingleOrDefaultAsync(CancellationToken)][2] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefaultAsync(OperatorStringHandler, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | **SingleOrDefaultAsync(String, CancellationToken)** | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public ValueTask SingleOrDefaultAsync( string predicate, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7]<[TResult][8]> The single element of the set that satisfies the condition, or a default value if no such element is found. See Also -------- #### Reference [SqlSet<TResult> Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefaultAsync_2.md [3]: SingleOrDefaultAsync.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/SingleOrDefaultAsync_2.md ================================================ SqlSet<TResult>.SingleOrDefaultAsync(CancellationToken) Method ================================================================= Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **SingleOrDefaultAsync(CancellationToken)** | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefaultAsync(OperatorStringHandler, CancellationToken)][2] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefaultAsync(String, CancellationToken)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public ValueTask SingleOrDefaultAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6]<[TResult][7]> The single element of the set, or a default value if the set contains no elements. Exceptions ---------- | Exception | Condition | | ------------------------------ | --------------------------------------- | | [InvalidOperationException][8] | The set contains more than one element. | See Also -------- #### Reference [SqlSet<TResult> Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefaultAsync.md [3]: SingleOrDefaultAsync_1.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [7]: README.md [8]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/SingleOrDefault_1.md ================================================ SqlSet<TResult>.SingleOrDefault(SqlSet.OperatorStringHandler) Method ======================================================================= Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [SingleOrDefault()][2] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | **SingleOrDefault(OperatorStringHandler)** | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | [SingleOrDefault(String)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public TResult SingleOrDefault( ref OperatorStringHandler? predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [TResult][4] The single element of the set that satisfies the condition, or a default value if no such element is found. See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefault.md [3]: SingleOrDefault_2.md [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/SingleOrDefault_2.md ================================================ SqlSet<TResult>.SingleOrDefault(String) Method ================================================= Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [SingleOrDefault()][2] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. | | [SingleOrDefault(OperatorStringHandler)][3] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | | **SingleOrDefault(String)** | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. | Syntax ------ ```csharp public TResult SingleOrDefault( string predicate ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. #### Return Value [TResult][5] The single element of the set that satisfies the condition, or a default value if no such element is found. See Also -------- #### Reference [SqlSet<TResult> Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: SingleOrDefault.md [3]: SingleOrDefault_1.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Single_1.md ================================================ SqlSet<TResult>.Single(SqlSet.OperatorStringHandler) Method ============================================================== Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | [Single()][2] | The single element of the set. | | **Single(OperatorStringHandler)** | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | [Single(String)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public TResult Single( ref OperatorStringHandler predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [TResult][4] The single element of the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | [InvalidOperationException][5] | No element satisfies the condition in *predicate*.-or-More than one element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: Single.md [3]: Single_2.md [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Single_2.md ================================================ SqlSet<TResult>.Single(String) Method ======================================== Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | [Single()][2] | The single element of the set. | | [Single(OperatorStringHandler)][3] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | | **Single(String)** | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. | Syntax ------ ```csharp public TResult Single( string predicate ) ``` #### Parameters ##### *predicate*  [String][4] A SQL expression to test each row for a condition. #### Return Value [TResult][5] The single element of the set that passes the test in the specified *predicate*. Exceptions ---------- | Exception | Condition | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | [InvalidOperationException][6] | No element satisfies the condition in *predicate*.-or-More than one element satisfies the condition in *predicate*.-or-The set is empty. | See Also -------- #### Reference [SqlSet<TResult> Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: Single.md [3]: Single_1.md [4]: https://learn.microsoft.com/dotnet/api/system.string [5]: README.md [6]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Skip.md ================================================ SqlSet<TResult>.Skip Method ============================== Bypasses a specified number of elements in the set and then returns the remaining elements. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlSet Skip( int count ) ``` #### Parameters ##### *count*  [Int32][2] The number of elements to skip before returning the remaining elements. #### Return Value [SqlSet][3]<[TResult][3]> A new [SqlSet<TResult>][3] that contains the elements that occur after the specified index in the current set. See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.int32 [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Take.md ================================================ SqlSet<TResult>.Take Method ============================== Returns a specified number of contiguous elements from the start of the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public SqlSet Take( int count ) ``` #### Parameters ##### *count*  [Int32][2] The number of elements to return. #### Return Value [SqlSet][3]<[TResult][3]> A new [SqlSet<TResult>][3] that contains the specified number of elements from the start of the current set. See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.int32 [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/ToArray.md ================================================ SqlSet<TResult>.ToArray Method ================================= Creates an array from the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public TResult[] ToArray() ``` #### Return Value [TResult][2][] An array that contains the elements from the set. See Also -------- #### Reference [SqlSet<TResult> Class][2] [DbExtensions Namespace][1] [1]: ../README.md [2]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/ToArrayAsync.md ================================================ SqlSet<TResult>.ToArrayAsync Method ====================================== Creates an array from the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask ToArrayAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][2]  (Optional) The [CancellationToken][2] to monitor for cancellation requests. The default is [None][3]. #### Return Value [ValueTask][4]<[TResult][5][]> An array that contains the elements from the set. See Also -------- #### Reference [SqlSet<TResult> Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [4]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/ToList.md ================================================ SqlSet<TResult>.ToList Method ================================ Creates a List<TResult> from the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public List ToList() ``` #### Return Value [List][2]<[TResult][3]> A List<TResult> that contains elements from the set. See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.collections.generic.list-1 [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/ToListAsync.md ================================================ SqlSet<TResult>.ToListAsync Method ===================================== Creates a List<TResult> from the set. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask> ToListAsync( CancellationToken cancellationToken = default ) ``` #### Parameters ##### *cancellationToken*  [CancellationToken][2]  (Optional) The [CancellationToken][2] to monitor for cancellation requests. The default is [None][3]. #### Return Value [ValueTask][4]<[List][5]<[TResult][6]>> A List<TResult> that contains elements from the set. See Also -------- #### Reference [SqlSet<TResult> Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [4]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [5]: https://learn.microsoft.com/dotnet/api/system.collections.generic.list-1 [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Where.md ================================================ SqlSet<TResult>.Where(SqlSet.OperatorStringHandler) Method ============================================================= Filters the set based on a predicate. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------- | ------------------------------------- | | **Where(OperatorStringHandler)** | Filters the set based on a predicate. | | [Where(String)][2] | Filters the set based on a predicate. | Syntax ------ ```csharp public SqlSet Where( ref OperatorStringHandler predicate ) ``` #### Parameters ##### *predicate*  OperatorStringHandler A SQL expression to test each row for a condition. #### Return Value [SqlSet][3]<[TResult][3]> A new [SqlSet<TResult>][3] that contains elements from the current set that satisfy the condition. See Also -------- #### Reference [SqlSet<TResult> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: Where_1.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlSet_1/Where_1.md ================================================ SqlSet<TResult>.Where(String) Method ======================================= Filters the set based on a predicate. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------- | ------------------------------------- | | [Where(OperatorStringHandler)][2] | Filters the set based on a predicate. | | **Where(String)** | Filters the set based on a predicate. | Syntax ------ ```csharp public SqlSet Where( string predicate ) ``` #### Parameters ##### *predicate*  [String][3] A SQL expression to test each row for a condition. #### Return Value [SqlSet][4]<[TResult][4]> A new [SqlSet<TResult>][4] that contains elements from the current set that satisfy the condition. See Also -------- #### Reference [SqlSet<TResult> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: Where.md [3]: https://learn.microsoft.com/dotnet/api/system.string [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/Add.md ================================================ SqlTable.Add Method =================== Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public void Add( Object entity ) ``` #### Parameters ##### *entity*  [Object][2] The object whose INSERT command is to be executed. This parameter is named entity for consistency with the other CRUD methods, but in this case it doesn't need to be an actual entity, which means it doesn't need to have a primary key. See Also -------- #### Reference [SqlTable Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/AddAsync.md ================================================ SqlTable.AddAsync Method ======================== Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask AddAsync( Object entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [Object][2] The object whose INSERT command is to be executed. This parameter is named entity for consistency with the other CRUD methods, but in this case it doesn't need to be an actual entity, which means it doesn't need to have a primary key. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5] See Also -------- #### Reference [SqlTable Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/AddRange.md ================================================ SqlTable.AddRange(IEnumerable<Object>) Method ================================================ Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | | **AddRange(IEnumerable<Object>)** | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [AddRange(Object[])][2] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | Syntax ------ ```csharp public void AddRange( IEnumerable entities ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[Object][4]> The entities whose INSERT commands are to be executed. See Also -------- #### Reference [SqlTable Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: AddRange_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/AddRangeAsync.md ================================================ SqlTable.AddRangeAsync(IEnumerable<Object>, CancellationToken) Method ======================================================================== Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | | [AddRangeAsync(Object[])][2] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | **AddRangeAsync(IEnumerable<Object>, CancellationToken)** | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | Syntax ------ ```csharp public ValueTask AddRangeAsync( IEnumerable entities, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[Object][4]> The entities whose INSERT commands are to be executed. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7] See Also -------- #### Reference [SqlTable Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: AddRangeAsync_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/AddRangeAsync_1.md ================================================ SqlTable.AddRangeAsync(Object[]) Method ======================================= Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | **AddRangeAsync(Object[])** | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [AddRangeAsync(IEnumerable<Object>, CancellationToken)][2] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | Syntax ------ ```csharp public ValueTask AddRangeAsync( params Object[] entities ) ``` #### Parameters ##### *entities*  [Object][3][] The entities whose INSERT commands are to be executed. #### Return Value [ValueTask][4] See Also -------- #### Reference [SqlTable Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: AddRangeAsync.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/AddRange_1.md ================================================ SqlTable.AddRange(Object[]) Method ================================== Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | [AddRange(IEnumerable<Object>)][2] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | **AddRange(Object[])** | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | Syntax ------ ```csharp public void AddRange( params Object[] entities ) ``` #### Parameters ##### *entities*  [Object][3][] The entities whose INSERT commands are to be executed. See Also -------- #### Reference [SqlTable Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: AddRange.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/Cast__1.md ================================================ SqlTable.Cast<TEntity> Method ================================ Casts the current [SqlTable][1] to the generic [SqlTable<TEntity>][2] instance. **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------- | ---------------------------------------------------------------------------------- | | [Cast(Type)][4] | Casts the elements of the set to the specified type. | | **Cast<TEntity>()** | Casts the current [SqlTable][1] to the generic [SqlTable<TEntity>][2] instance. | Syntax ------ ```csharp public SqlTable Cast() where TEntity : class ``` #### Type Parameters ##### *TEntity* The type of the entity. #### Return Value [SqlTable][2]<**TEntity**> The [SqlTable<TEntity>][2] instance for TEntity. Exceptions ---------- | Exception | Condition | | ------------------------------ | ----------------------------------------------------- | | [InvalidOperationException][5] | The specified TEntity is not valid for this instance. | See Also -------- #### Reference [SqlTable Class][1] [DbExtensions Namespace][3] [1]: README.md [2]: ../SqlTable_1/README.md [3]: ../README.md [4]: ../SqlSet/Cast.md [5]: https://learn.microsoft.com/dotnet/api/system.invalidoperationexception ================================================ FILE: docs/api/DbExtensions/SqlTable/Name.md ================================================ SqlTable.Name Property ====================== Gets the name of the table. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string Name { get; } ``` #### Property Value [String][2] See Also -------- #### Reference [SqlTable Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/README.md ================================================ SqlTable Class ============== A non-generic version of [SqlTable<TEntity>][1] which can be used when the type of the entity is not known at build time. This class cannot be instantiated, to get an instance use the [Database.Table(Type)][2] method. Inheritance Hierarchy --------------------- [System.Object][3]   [DbExtensions.SqlSet][4]     **DbExtensions.SqlTable** **Namespace:** [DbExtensions][5] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public sealed class SqlTable : SqlSet ``` The **SqlTable** type exposes the following members. Properties ---------- | Name | Description | | --------------- | -------------------------------------------------------------------------------------------------- | | [Database][6] | The [Database][7] this set is connected to.
(Inherited from [SqlSet][4]) | | [Name][8] | Gets the name of the table. | | [ResultType][9] | The type of objects this set returns. This property can be null.
(Inherited from [SqlSet][4]) | Methods ------- | Name | Description | | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | [Add][10] | Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. | | [AddAsync][11] | Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. | | [AddRange(IEnumerable<Object>)][12] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [AddRange(Object[])][13] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [AddRangeAsync(Object[])][14] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [AddRangeAsync(IEnumerable<Object>, CancellationToken)][15] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [All(OperatorStringHandler)][16] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [All(String)][17] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [AllAsync(OperatorStringHandler, CancellationToken)][18] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [AllAsync(String, CancellationToken)][19] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [Any()][20] | Determines whether the set contains any elements.
(Inherited from [SqlSet][4]) | | [Any(OperatorStringHandler)][21] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [Any(String)][22] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [AnyAsync(CancellationToken)][23] | Determines whether the set contains any elements.
(Inherited from [SqlSet][4]) | | [AnyAsync(OperatorStringHandler, CancellationToken)][24] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [AnyAsync(String, CancellationToken)][25] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [AsAsyncEnumerable][26] | Gets all elements in the set. The query is deferred-executed.
(Inherited from [SqlSet][4]) | | [AsEnumerable][27] | Gets all elements in the set. The query is deferred-executed.
(Inherited from [SqlSet][4]) | | [Cast(Type)][28] | Casts the elements of the set to the specified type.
(Inherited from [SqlSet][4]) | | [Cast<TEntity>()][29] | Casts the current **SqlTable** to the generic [SqlTable<TEntity>][1] instance. | | [Contains][30] | Checks the existance of the *entity*, using the primary key value.
(Inherited from [SqlSet][4]) | | [ContainsAsync][31] | Checks the existance of the *entity*, using the primary key value.
(Inherited from [SqlSet][4]) | | [ContainsKey][32] | Checks the existance of an entity whose primary matches the *id* parameter.
(Inherited from [SqlSet][4]) | | [ContainsKeyAsync][33] | Checks the existance of an entity whose primary matches the *id* parameter.
(Inherited from [SqlSet][4]) | | [Count()][34] | Returns the number of elements in the set.
(Inherited from [SqlSet][4]) | | [Count(OperatorStringHandler)][35] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [Count(String)][36] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [CountAsync(CancellationToken)][37] | Returns the number of elements in the set.
(Inherited from [SqlSet][4]) | | [CountAsync(OperatorStringHandler, CancellationToken)][38] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [CountAsync(String, CancellationToken)][39] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [Find][40] | Gets the entity whose primary key matches the *id* parameter.
(Inherited from [SqlSet][4]) | | [FindAsync][41] | Gets the entity whose primary key matches the *id* parameter.
(Inherited from [SqlSet][4]) | | [First()][42] | Returns the first element of the set.
(Inherited from [SqlSet][4]) | | [First(OperatorStringHandler)][43] | Returns the first element in the set that satisfies a specified condition.
(Inherited from [SqlSet][4]) | | [First(String)][44] | Returns the first element in the set that satisfies a specified condition.
(Inherited from [SqlSet][4]) | | [FirstAsync(CancellationToken)][45] | Returns the first element of the set.
(Inherited from [SqlSet][4]) | | [FirstAsync(OperatorStringHandler, CancellationToken)][46] | Returns the first element in the set that satisfies a specified condition.
(Inherited from [SqlSet][4]) | | [FirstAsync(String, CancellationToken)][47] | Returns the first element in the set that satisfies a specified condition.
(Inherited from [SqlSet][4]) | | [FirstOrDefault()][48] | Returns the first element of the set, or a default value if the set contains no elements.
(Inherited from [SqlSet][4]) | | [FirstOrDefault(OperatorStringHandler)][49] | Returns the first element of the set that satisfies a condition or a default value if no such element is found.
(Inherited from [SqlSet][4]) | | [FirstOrDefault(String)][50] | Returns the first element of the set that satisfies a condition or a default value if no such element is found.
(Inherited from [SqlSet][4]) | | [FirstOrDefaultAsync(CancellationToken)][51] | Returns the first element of the set, or a default value if the set contains no elements.
(Inherited from [SqlSet][4]) | | [FirstOrDefaultAsync(OperatorStringHandler, CancellationToken)][52] | Returns the first element of the set that satisfies a condition or a default value if no such element is found.
(Inherited from [SqlSet][4]) | | [FirstOrDefaultAsync(String, CancellationToken)][53] | Returns the first element of the set that satisfies a condition or a default value if no such element is found.
(Inherited from [SqlSet][4]) | | [GetAsyncEnumerator][54] | Returns an async enumerator that iterates through the set.
(Inherited from [SqlSet][4]) | | [GetDefiningQuery][55] | Returns the SQL query that is the source of data for the set.
(Inherited from [SqlSet][4]) | | [GetEnumerator][56] | Returns an enumerator that iterates through the set.
(Inherited from [SqlSet][4]) | | [Include][57] | Specifies the related objects to include in the query results.
(Inherited from [SqlSet][4]) | | [IncludeMany][58] | Specifies which collections to include in the query results.
(Inherited from [SqlSet][4]) | | [LongCount()][59] | Returns an [Int64][60] that represents the total number of elements in the set.
(Inherited from [SqlSet][4]) | | [LongCount(OperatorStringHandler)][61] | Returns an [Int64][60] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [LongCount(String)][62] | Returns an [Int64][60] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [LongCountAsync(CancellationToken)][63] | Returns an [Int64][60] that represents the total number of elements in the set.
(Inherited from [SqlSet][4]) | | [LongCountAsync(OperatorStringHandler, CancellationToken)][64] | Returns an [Int64][60] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [LongCountAsync(String, CancellationToken)][65] | Returns an [Int64][60] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [OrderBy(OperatorStringHandler)][66] | Sorts the elements of the set according to the *columnList*.
(Inherited from [SqlSet][4]) | | [OrderBy(String)][67] | Sorts the elements of the set according to the *columnList*.
(Inherited from [SqlSet][4]) | | [Refresh][68] | Sets all column members of *entity* to their most current persisted value. | | [RefreshAsync][69] | Sets all column members of *entity* to their most current persisted value. | | [Remove][70] | Executes a DELETE command for the specified *entity*. | | [RemoveAsync][71] | Executes a DELETE command for the specified *entity*. | | [RemoveKey][72] | Executes a DELETE command for the entity whose primary key matches the *id* parameter. | | [RemoveKeyAsync][73] | Executes a DELETE command for the entity whose primary key matches the *id* parameter. | | [RemoveRange(IEnumerable<Object>)][74] | Executes DELETE commands for the specified *entities*. | | [RemoveRange(Object[])][75] | Executes DELETE commands for the specified *entities*. | | [RemoveRangeAsync(Object[])][76] | Executes DELETE commands for the specified *entities*. | | [RemoveRangeAsync(IEnumerable<Object>, CancellationToken)][77] | Executes DELETE commands for the specified *entities*. | | [Select(OperatorStringHandler, Type)][78] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select(String, Type)][79] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(OperatorStringHandler)][80] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(String)][81] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][82] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(String, Func<DbDataReader, TResult>)][83] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Single()][84] | The single element of the set.
(Inherited from [SqlSet][4]) | | [Single(OperatorStringHandler)][85] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists.
(Inherited from [SqlSet][4]) | | [Single(String)][86] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists.
(Inherited from [SqlSet][4]) | | [SingleAsync(CancellationToken)][87] | The single element of the set.
(Inherited from [SqlSet][4]) | | [SingleAsync(OperatorStringHandler, CancellationToken)][88] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists.
(Inherited from [SqlSet][4]) | | [SingleAsync(String, CancellationToken)][89] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists.
(Inherited from [SqlSet][4]) | | [SingleOrDefault()][90] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set.
(Inherited from [SqlSet][4]) | | [SingleOrDefault(OperatorStringHandler)][91] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition.
(Inherited from [SqlSet][4]) | | [SingleOrDefault(String)][92] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition.
(Inherited from [SqlSet][4]) | | [SingleOrDefaultAsync(CancellationToken)][93] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set.
(Inherited from [SqlSet][4]) | | [SingleOrDefaultAsync(OperatorStringHandler, CancellationToken)][94] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition.
(Inherited from [SqlSet][4]) | | [SingleOrDefaultAsync(String, CancellationToken)][95] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition.
(Inherited from [SqlSet][4]) | | [Skip][96] | Bypasses a specified number of elements in the set and then returns the remaining elements.
(Inherited from [SqlSet][4]) | | [Take][97] | Returns a specified number of contiguous elements from the start of the set.
(Inherited from [SqlSet][4]) | | [ToArray][98] | Creates an array from the set.
(Inherited from [SqlSet][4]) | | [ToArrayAsync][99] | Creates an array from the set.
(Inherited from [SqlSet][4]) | | [ToList][100] | Creates a [List<T>][101] from the set.
(Inherited from [SqlSet][4]) | | [ToListAsync][102] | Creates a [List<T>][101] from the set.
(Inherited from [SqlSet][4]) | | [ToString][103] | Returns the SQL query of the set.
(Inherited from [SqlSet][4]) | | [Update(Object)][104] | Executes an UPDATE command for the specified *entity*. | | [Update(Object, Object)][105] | Executes an UPDATE command for the specified *entity*. | | [UpdateAsync(Object, CancellationToken)][106] | Executes an UPDATE command for the specified *entity*. | | [UpdateAsync(Object, Object, CancellationToken)][107] | Executes an UPDATE command for the specified *entity*. | | [UpdateRange(IEnumerable<Object>)][108] | Executes UPDATE commands for the specified *entities*. | | [UpdateRange(Object[])][109] | Executes UPDATE commands for the specified *entities*. | | [UpdateRangeAsync(Object[])][110] | Executes UPDATE commands for the specified *entities*. | | [UpdateRangeAsync(IEnumerable<Object>, CancellationToken)][111] | Executes UPDATE commands for the specified *entities*. | | [Where(OperatorStringHandler)][112] | Filters the set based on a predicate.
(Inherited from [SqlSet][4]) | | [Where(String)][113] | Filters the set based on a predicate.
(Inherited from [SqlSet][4]) | See Also -------- #### Reference [DbExtensions Namespace][5] [1]: ../SqlTable_1/README.md [2]: ../Database/Table.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: ../SqlSet/README.md [5]: ../README.md [6]: ../SqlSet/Database.md [7]: ../Database/README.md [8]: Name.md [9]: ../SqlSet/ResultType.md [10]: Add.md [11]: AddAsync.md [12]: AddRange.md [13]: AddRange_1.md [14]: AddRangeAsync_1.md [15]: AddRangeAsync.md [16]: ../SqlSet/All.md [17]: ../SqlSet/All_1.md [18]: ../SqlSet/AllAsync.md [19]: ../SqlSet/AllAsync_1.md [20]: ../SqlSet/Any.md [21]: ../SqlSet/Any_1.md [22]: ../SqlSet/Any_2.md [23]: ../SqlSet/AnyAsync_2.md [24]: ../SqlSet/AnyAsync.md [25]: ../SqlSet/AnyAsync_1.md [26]: ../SqlSet/AsAsyncEnumerable.md [27]: ../SqlSet/AsEnumerable.md [28]: ../SqlSet/Cast.md [29]: Cast__1.md [30]: ../SqlSet/Contains.md [31]: ../SqlSet/ContainsAsync.md [32]: ../SqlSet/ContainsKey.md [33]: ../SqlSet/ContainsKeyAsync.md [34]: ../SqlSet/Count.md [35]: ../SqlSet/Count_1.md [36]: ../SqlSet/Count_2.md [37]: ../SqlSet/CountAsync_2.md [38]: ../SqlSet/CountAsync.md [39]: ../SqlSet/CountAsync_1.md [40]: ../SqlSet/Find.md [41]: ../SqlSet/FindAsync.md [42]: ../SqlSet/First.md [43]: ../SqlSet/First_1.md [44]: ../SqlSet/First_2.md [45]: ../SqlSet/FirstAsync_2.md [46]: ../SqlSet/FirstAsync.md [47]: ../SqlSet/FirstAsync_1.md [48]: ../SqlSet/FirstOrDefault.md [49]: ../SqlSet/FirstOrDefault_1.md [50]: ../SqlSet/FirstOrDefault_2.md [51]: ../SqlSet/FirstOrDefaultAsync_2.md [52]: ../SqlSet/FirstOrDefaultAsync.md [53]: ../SqlSet/FirstOrDefaultAsync_1.md [54]: ../SqlSet/GetAsyncEnumerator.md [55]: ../SqlSet/GetDefiningQuery.md [56]: ../SqlSet/GetEnumerator.md [57]: ../SqlSet/Include.md [58]: ../SqlSet/IncludeMany.md [59]: ../SqlSet/LongCount.md [60]: https://learn.microsoft.com/dotnet/api/system.int64 [61]: ../SqlSet/LongCount_1.md [62]: ../SqlSet/LongCount_2.md [63]: ../SqlSet/LongCountAsync_2.md [64]: ../SqlSet/LongCountAsync.md [65]: ../SqlSet/LongCountAsync_1.md [66]: ../SqlSet/OrderBy.md [67]: ../SqlSet/OrderBy_1.md [68]: Refresh.md [69]: RefreshAsync.md [70]: Remove.md [71]: RemoveAsync.md [72]: RemoveKey.md [73]: RemoveKeyAsync.md [74]: RemoveRange.md [75]: RemoveRange_1.md [76]: RemoveRangeAsync_1.md [77]: RemoveRangeAsync.md [78]: ../SqlSet/Select_1.md [79]: ../SqlSet/Select_3.md [80]: ../SqlSet/Select__1.md [81]: ../SqlSet/Select__1_2.md [82]: ../SqlSet/Select__1_1.md [83]: ../SqlSet/Select__1_3.md [84]: ../SqlSet/Single.md [85]: ../SqlSet/Single_1.md [86]: ../SqlSet/Single_2.md [87]: ../SqlSet/SingleAsync_2.md [88]: ../SqlSet/SingleAsync.md [89]: ../SqlSet/SingleAsync_1.md [90]: ../SqlSet/SingleOrDefault.md [91]: ../SqlSet/SingleOrDefault_1.md [92]: ../SqlSet/SingleOrDefault_2.md [93]: ../SqlSet/SingleOrDefaultAsync_2.md [94]: ../SqlSet/SingleOrDefaultAsync.md [95]: ../SqlSet/SingleOrDefaultAsync_1.md [96]: ../SqlSet/Skip.md [97]: ../SqlSet/Take.md [98]: ../SqlSet/ToArray.md [99]: ../SqlSet/ToArrayAsync.md [100]: ../SqlSet/ToList.md [101]: https://learn.microsoft.com/dotnet/api/system.collections.generic.list-1 [102]: ../SqlSet/ToListAsync.md [103]: ../SqlSet/ToString.md [104]: Update.md [105]: Update_1.md [106]: UpdateAsync_1.md [107]: UpdateAsync.md [108]: UpdateRange.md [109]: UpdateRange_1.md [110]: UpdateRangeAsync_1.md [111]: UpdateRangeAsync.md [112]: ../SqlSet/Where.md [113]: ../SqlSet/Where_1.md ================================================ FILE: docs/api/DbExtensions/SqlTable/Refresh.md ================================================ SqlTable.Refresh Method ======================= Sets all column members of *entity* to their most current persisted value. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public void Refresh( Object entity ) ``` #### Parameters ##### *entity*  [Object][2] The entity to refresh. See Also -------- #### Reference [SqlTable Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/RefreshAsync.md ================================================ SqlTable.RefreshAsync Method ============================ Sets all column members of *entity* to their most current persisted value. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask RefreshAsync( Object entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [Object][2] The entity to refresh. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5] See Also -------- #### Reference [SqlTable Class][6] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [6]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/Remove.md ================================================ SqlTable.Remove Method ====================== Executes a DELETE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool Remove( Object entity ) ``` #### Parameters ##### *entity*  [Object][2] The entity whose DELETE command is to be executed. #### Return Value [Boolean][3] `true` if *entity* is deleted; otherwise, `false`. See Also -------- #### Reference [SqlTable Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.boolean [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/RemoveAsync.md ================================================ SqlTable.RemoveAsync Method =========================== Executes a DELETE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask RemoveAsync( Object entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [Object][2] The entity whose DELETE command is to be executed. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[Boolean][6]> `true` if *entity* is deleted; otherwise, `false`. See Also -------- #### Reference [SqlTable Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.boolean [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/RemoveKey.md ================================================ SqlTable.RemoveKey Method ========================= Executes a DELETE command for the entity whose primary key matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool RemoveKey( Object id ) ``` #### Parameters ##### *id*  [Object][2] The primary key value. #### Return Value [Boolean][3] `true` if a record that matches *id* was found and deleted; otherwise, `false`. See Also -------- #### Reference [SqlTable Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.boolean [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/RemoveKeyAsync.md ================================================ SqlTable.RemoveKeyAsync Method ============================== Executes a DELETE command for the entity whose primary key matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask RemoveKeyAsync( Object id, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *id*  [Object][2] The primary key value. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[Boolean][6]> `true` if a record that matches *id* was found and deleted; otherwise, `false`. See Also -------- #### Reference [SqlTable Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.boolean [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/RemoveRange.md ================================================ SqlTable.RemoveRange(IEnumerable<Object>) Method =================================================== Executes DELETE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------- | ------------------------------------------------------ | | **RemoveRange(IEnumerable<Object>)** | Executes DELETE commands for the specified *entities*. | | [RemoveRange(Object[])][2] | Executes DELETE commands for the specified *entities*. | Syntax ------ ```csharp public void RemoveRange( IEnumerable entities ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[Object][4]> The entities whose DELETE commands are to be executed. See Also -------- #### Reference [SqlTable Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: RemoveRange_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/RemoveRangeAsync.md ================================================ SqlTable.RemoveRangeAsync(IEnumerable<Object>, CancellationToken) Method =========================================================================== Executes DELETE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------------- | ------------------------------------------------------ | | [RemoveRangeAsync(Object[])][2] | Executes DELETE commands for the specified *entities*. | | **RemoveRangeAsync(IEnumerable<Object>, CancellationToken)** | Executes DELETE commands for the specified *entities*. | Syntax ------ ```csharp public ValueTask RemoveRangeAsync( IEnumerable entities, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[Object][4]> The entities whose DELETE commands are to be executed. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7] See Also -------- #### Reference [SqlTable Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: RemoveRangeAsync_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/RemoveRangeAsync_1.md ================================================ SqlTable.RemoveRangeAsync(Object[]) Method ========================================== Executes DELETE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------- | ------------------------------------------------------ | | **RemoveRangeAsync(Object[])** | Executes DELETE commands for the specified *entities*. | | [RemoveRangeAsync(IEnumerable<Object>, CancellationToken)][2] | Executes DELETE commands for the specified *entities*. | Syntax ------ ```csharp public ValueTask RemoveRangeAsync( params Object[] entities ) ``` #### Parameters ##### *entities*  [Object][3][] The entities whose DELETE commands are to be executed. #### Return Value [ValueTask][4] See Also -------- #### Reference [SqlTable Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: RemoveRangeAsync.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/RemoveRange_1.md ================================================ SqlTable.RemoveRange(Object[]) Method ===================================== Executes DELETE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------- | ------------------------------------------------------ | | [RemoveRange(IEnumerable<Object>)][2] | Executes DELETE commands for the specified *entities*. | | **RemoveRange(Object[])** | Executes DELETE commands for the specified *entities*. | Syntax ------ ```csharp public void RemoveRange( params Object[] entities ) ``` #### Parameters ##### *entities*  [Object][3][] The entities whose DELETE commands are to be executed. See Also -------- #### Reference [SqlTable Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: RemoveRange.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/Update.md ================================================ SqlTable.Update(Object) Method ============================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------- | ------------------------------------------------------ | | **Update(Object)** | Executes an UPDATE command for the specified *entity*. | | [Update(Object, Object)][2] | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public void Update( Object entity ) ``` #### Parameters ##### *entity*  [Object][3] The entity whose UPDATE command is to be executed. See Also -------- #### Reference [SqlTable Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: Update_1.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/UpdateAsync.md ================================================ SqlTable.UpdateAsync(Object, Object, CancellationToken) Method ============================================================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------- | ------------------------------------------------------ | | [UpdateAsync(Object, CancellationToken)][2] | Executes an UPDATE command for the specified *entity*. | | **UpdateAsync(Object, Object, CancellationToken)** | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public ValueTask UpdateAsync( Object entity, Object? originalId, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [Object][3] The entity whose UPDATE command is to be executed. ##### *originalId*  [Object][3] The original primary key value. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6] Remarks ------- This overload is helpful when the entity uses an assigned primary key. See Also -------- #### Reference [SqlTable Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateAsync_1.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/UpdateAsync_1.md ================================================ SqlTable.UpdateAsync(Object, CancellationToken) Method ====================================================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------- | ------------------------------------------------------ | | **UpdateAsync(Object, CancellationToken)** | Executes an UPDATE command for the specified *entity*. | | [UpdateAsync(Object, Object, CancellationToken)][2] | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public ValueTask UpdateAsync( Object entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [Object][3] The entity whose UPDATE command is to be executed. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6] See Also -------- #### Reference [SqlTable Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateAsync.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/UpdateRange.md ================================================ SqlTable.UpdateRange(IEnumerable<Object>) Method =================================================== Executes UPDATE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------- | ------------------------------------------------------ | | **UpdateRange(IEnumerable<Object>)** | Executes UPDATE commands for the specified *entities*. | | [UpdateRange(Object[])][2] | Executes UPDATE commands for the specified *entities*. | Syntax ------ ```csharp public void UpdateRange( IEnumerable entities ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[Object][4]> The entities whose UPDATE commands are to be executed. See Also -------- #### Reference [SqlTable Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateRange_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/UpdateRangeAsync.md ================================================ SqlTable.UpdateRangeAsync(IEnumerable<Object>, CancellationToken) Method =========================================================================== Executes UPDATE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------------------- | ------------------------------------------------------ | | [UpdateRangeAsync(Object[])][2] | Executes UPDATE commands for the specified *entities*. | | **UpdateRangeAsync(IEnumerable<Object>, CancellationToken)** | Executes UPDATE commands for the specified *entities*. | Syntax ------ ```csharp public ValueTask UpdateRangeAsync( IEnumerable entities, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[Object][4]> The entities whose UPDATE commands are to be executed. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7] See Also -------- #### Reference [SqlTable Class][8] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateRangeAsync_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [8]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/UpdateRangeAsync_1.md ================================================ SqlTable.UpdateRangeAsync(Object[]) Method ========================================== Executes UPDATE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------- | ------------------------------------------------------ | | **UpdateRangeAsync(Object[])** | Executes UPDATE commands for the specified *entities*. | | [UpdateRangeAsync(IEnumerable<Object>, CancellationToken)][2] | Executes UPDATE commands for the specified *entities*. | Syntax ------ ```csharp public ValueTask UpdateRangeAsync( params Object[] entities ) ``` #### Parameters ##### *entities*  [Object][3][] The entities whose UPDATE commands are to be executed. #### Return Value [ValueTask][4] See Also -------- #### Reference [SqlTable Class][5] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateRangeAsync.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask [5]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/UpdateRange_1.md ================================================ SqlTable.UpdateRange(Object[]) Method ===================================== Executes UPDATE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------- | ------------------------------------------------------ | | [UpdateRange(IEnumerable<Object>)][2] | Executes UPDATE commands for the specified *entities*. | | **UpdateRange(Object[])** | Executes UPDATE commands for the specified *entities*. | Syntax ------ ```csharp public void UpdateRange( params Object[] entities ) ``` #### Parameters ##### *entities*  [Object][3][] The entities whose UPDATE commands are to be executed. See Also -------- #### Reference [SqlTable Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateRange.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable/Update_1.md ================================================ SqlTable.Update(Object, Object) Method ====================================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------- | ------------------------------------------------------ | | [Update(Object)][2] | Executes an UPDATE command for the specified *entity*. | | **Update(Object, Object)** | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public void Update( Object entity, Object? originalId ) ``` #### Parameters ##### *entity*  [Object][3] The entity whose UPDATE command is to be executed. ##### *originalId*  [Object][3] The original primary key value. Remarks ------- This overload is helpful when the entity uses an assigned primary key. See Also -------- #### Reference [SqlTable Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: Update.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/Add.md ================================================ SqlTable<TEntity>.Add Method =============================== Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public void Add( TEntity entity ) ``` #### Parameters ##### *entity*  [TEntity][2] The object whose INSERT command is to be executed. This parameter is named entity for consistency with the other CRUD methods, but in this case it doesn't need to be an actual entity, which means it doesn't need to have a primary key. See Also -------- #### Reference [SqlTable<TEntity> Class][2] [DbExtensions Namespace][1] [1]: ../README.md [2]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/AddAsync.md ================================================ SqlTable<TEntity>.AddAsync Method ==================================== Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask AddAsync( TEntity entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [TEntity][2] The object whose INSERT command is to be executed. This parameter is named entity for consistency with the other CRUD methods, but in this case it doesn't need to be an actual entity, which means it doesn't need to have a primary key. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5] See Also -------- #### Reference [SqlTable<TEntity> Class][2] [DbExtensions Namespace][1] [1]: ../README.md [2]: README.md [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask ================================================ FILE: docs/api/DbExtensions/SqlTable_1/AddRange.md ================================================ SqlTable<TEntity>.AddRange(IEnumerable<TEntity>) Method ============================================================= Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | **AddRange(IEnumerable<TEntity>)** | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [AddRange(TEntity[])][2] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | Syntax ------ ```csharp public void AddRange( IEnumerable entities ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[TEntity][4]> The entities whose INSERT commands are to be executed. See Also -------- #### Reference [SqlTable<TEntity> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: AddRange_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/AddRangeAsync.md ================================================ SqlTable<TEntity>.AddRangeAsync(IEnumerable<TEntity>, CancellationToken) Method ===================================================================================== Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | [AddRangeAsync(TEntity[])][2] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | **AddRangeAsync(IEnumerable<TEntity>, CancellationToken)** | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | Syntax ------ ```csharp public ValueTask AddRangeAsync( IEnumerable entities, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[TEntity][4]> The entities whose INSERT commands are to be executed. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7] See Also -------- #### Reference [SqlTable<TEntity> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: AddRangeAsync_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask ================================================ FILE: docs/api/DbExtensions/SqlTable_1/AddRangeAsync_1.md ================================================ SqlTable<TEntity>.AddRangeAsync(TEntity[]) Method ==================================================== Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | **AddRangeAsync(TEntity[])** | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [AddRangeAsync(IEnumerable<TEntity>, CancellationToken)][2] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | Syntax ------ ```csharp public ValueTask AddRangeAsync( params TEntity[] entities ) ``` #### Parameters ##### *entities*  [TEntity][3][] The entities whose INSERT commands are to be executed. #### Return Value [ValueTask][4] See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: AddRangeAsync.md [3]: README.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask ================================================ FILE: docs/api/DbExtensions/SqlTable_1/AddRange_1.md ================================================ SqlTable<TEntity>.AddRange(TEntity[]) Method =============================================== Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | [AddRange(IEnumerable<TEntity>)][2] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | **AddRange(TEntity[])** | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | Syntax ------ ```csharp public void AddRange( params TEntity[] entities ) ``` #### Parameters ##### *entities*  [TEntity][3][] The entities whose INSERT commands are to be executed. See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: AddRange.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/Name.md ================================================ SqlTable<TEntity>.Name Property ================================== Gets the name of the table. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string Name { get; } ``` #### Property Value [String][2] See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/README.md ================================================ SqlTable<TEntity> Class ========================== A [SqlSet<TResult>][1] that provides CRUD (Create, Read, Update, Delete) operations for annotated classes. This class cannot be instantiated, to get an instance use the [Database.Table<TEntity>()][2] method. Inheritance Hierarchy --------------------- [System.Object][3]   [DbExtensions.SqlSet][4]     [DbExtensions.SqlSet][1]<**TEntity**>       **DbExtensions.SqlTable<TEntity>** **Namespace:** [DbExtensions][5] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public sealed class SqlTable : SqlSet where TEntity : class ``` #### Type Parameters ##### *TEntity* The type of the entity. The **SqlTable<TEntity>** type exposes the following members. Properties ---------- | Name | Description | | --------------- | -------------------------------------------------------------------------------------------------- | | [Database][6] | The [Database][7] this set is connected to.
(Inherited from [SqlSet][4]) | | [Name][8] | Gets the name of the table. | | [ResultType][9] | The type of objects this set returns. This property can be null.
(Inherited from [SqlSet][4]) | Methods ------- | Name | Description | | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | [Add][10] | Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. | | [AddAsync][11] | Recursively executes INSERT commands for the specified *entity* and all its one-to-one and one-to-many associations. | | [AddRange(IEnumerable<TEntity>)][12] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [AddRange(TEntity[])][13] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [AddRangeAsync(TEntity[])][14] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [AddRangeAsync(IEnumerable<TEntity>, CancellationToken)][15] | Recursively executes INSERT commands for the specified *entities* and all their one-to-one and one-to-many associations. | | [All(OperatorStringHandler)][16] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [All(String)][17] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [AllAsync(OperatorStringHandler, CancellationToken)][18] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [AllAsync(String, CancellationToken)][19] | Determines whether all elements of the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [Any()][20] | Determines whether the set contains any elements.
(Inherited from [SqlSet][4]) | | [Any(OperatorStringHandler)][21] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [Any(String)][22] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [AnyAsync(CancellationToken)][23] | Determines whether the set contains any elements.
(Inherited from [SqlSet][4]) | | [AnyAsync(OperatorStringHandler, CancellationToken)][24] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [AnyAsync(String, CancellationToken)][25] | Determines whether any element of the set satisfies a condition.
(Inherited from [SqlSet][4]) | | [AsAsyncEnumerable][26] | Gets all TResult objects in the set. The query is deferred-executed.
(Inherited from [SqlSet<TResult>][1]) | | [AsEnumerable][27] | Gets all TResult objects in the set. The query is deferred-executed.
(Inherited from [SqlSet<TResult>][1]) | | [Cast(Type)][28] | Casts the elements of the set to the specified type.
(Inherited from [SqlSet][4]) | | [Cast<TResult>()][29] | Casts the elements of the set to the specified type.
(Inherited from [SqlSet][4]) | | [Contains(Object)][30] | Checks the existance of the *entity*, using the primary key value.
(Inherited from [SqlSet][4]) | | [Contains(TResult)][31] | Checks the existance of the *entity*, using the primary key value.
(Inherited from [SqlSet<TResult>][1]) | | [ContainsAsync(Object, CancellationToken)][32] | Checks the existance of the *entity*, using the primary key value.
(Inherited from [SqlSet][4]) | | [ContainsAsync(TResult, CancellationToken)][33] | Checks the existance of the *entity*, using the primary key value.
(Inherited from [SqlSet<TResult>][1]) | | [ContainsKey][34] | Checks the existance of an entity whose primary matches the *id* parameter.
(Inherited from [SqlSet][4]) | | [ContainsKeyAsync][35] | Checks the existance of an entity whose primary matches the *id* parameter.
(Inherited from [SqlSet][4]) | | [Count()][36] | Returns the number of elements in the set.
(Inherited from [SqlSet][4]) | | [Count(OperatorStringHandler)][37] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [Count(String)][38] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [CountAsync(CancellationToken)][39] | Returns the number of elements in the set.
(Inherited from [SqlSet][4]) | | [CountAsync(OperatorStringHandler, CancellationToken)][40] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [CountAsync(String, CancellationToken)][41] | Returns a number that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [Find][42] | Gets the entity whose primary key matches the *id* parameter.
(Inherited from [SqlSet<TResult>][1]) | | [FindAsync][43] | Gets the entity whose primary key matches the *id* parameter.
(Inherited from [SqlSet<TResult>][1]) | | [First()][44] | Returns the first element of the set.
(Inherited from [SqlSet<TResult>][1]) | | [First(OperatorStringHandler)][45] | Returns the first element in the set that satisfies a specified condition.
(Inherited from [SqlSet<TResult>][1]) | | [First(String)][46] | Returns the first element in the set that satisfies a specified condition.
(Inherited from [SqlSet<TResult>][1]) | | [FirstAsync(CancellationToken)][47] | Returns the first element of the set.
(Inherited from [SqlSet<TResult>][1]) | | [FirstAsync(OperatorStringHandler, CancellationToken)][48] | Returns the first element in the set that satisfies a specified condition.
(Inherited from [SqlSet<TResult>][1]) | | [FirstAsync(String, CancellationToken)][49] | Returns the first element in the set that satisfies a specified condition.
(Inherited from [SqlSet<TResult>][1]) | | [FirstOrDefault()][50] | Returns the first element of the set, or a default value if the set contains no elements.
(Inherited from [SqlSet<TResult>][1]) | | [FirstOrDefault(OperatorStringHandler)][51] | Returns the first element of the set that satisfies a condition or a default value if no such element is found.
(Inherited from [SqlSet<TResult>][1]) | | [FirstOrDefault(String)][52] | Returns the first element of the set that satisfies a condition or a default value if no such element is found.
(Inherited from [SqlSet<TResult>][1]) | | [FirstOrDefaultAsync(CancellationToken)][53] | Returns the first element of the set, or a default value if the set contains no elements.
(Inherited from [SqlSet<TResult>][1]) | | [FirstOrDefaultAsync(OperatorStringHandler, CancellationToken)][54] | Returns the first element of the set that satisfies a condition or a default value if no such element is found.
(Inherited from [SqlSet<TResult>][1]) | | [FirstOrDefaultAsync(String, CancellationToken)][55] | Returns the first element of the set that satisfies a condition or a default value if no such element is found.
(Inherited from [SqlSet<TResult>][1]) | | [GetAsyncEnumerator][56] | Returns an async enumerator that iterates through the set.
(Inherited from [SqlSet<TResult>][1]) | | [GetDefiningQuery][57] | Returns the SQL query that is the source of data for the set.
(Inherited from [SqlSet][4]) | | [GetEnumerator][58] | Returns an enumerator that iterates through the set.
(Inherited from [SqlSet<TResult>][1]) | | [Include(String)][59] | Specifies the related objects to include in the query results.
(Inherited from [SqlSet<TResult>][1]) | | [Include(Func<TResult, Object>, String)][60] | Specifies the related objects to include in the query results.
(Inherited from [SqlSet<TResult>][1]) | | [IncludeMany(String, Func<SqlSet, SqlSet>)][61] | Specifies which collections to include in the query results.
(Inherited from [SqlSet<TResult>][1]) | | [IncludeMany<TElement>(Func<TResult, ICollection<TElement>>, Func<SqlSet<TElement>, SqlSet<TElement>>, String)][62] | Specifies which collections to include in the query results.
(Inherited from [SqlSet<TResult>][1]) | | [LongCount()][63] | Returns an [Int64][64] that represents the total number of elements in the set.
(Inherited from [SqlSet][4]) | | [LongCount(OperatorStringHandler)][65] | Returns an [Int64][64] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [LongCount(String)][66] | Returns an [Int64][64] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [LongCountAsync(CancellationToken)][67] | Returns an [Int64][64] that represents the total number of elements in the set.
(Inherited from [SqlSet][4]) | | [LongCountAsync(OperatorStringHandler, CancellationToken)][68] | Returns an [Int64][64] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [LongCountAsync(String, CancellationToken)][69] | Returns an [Int64][64] that represents how many elements in the set satisfy a condition.
(Inherited from [SqlSet][4]) | | [OrderBy(OperatorStringHandler)][70] | Sorts the elements of the set according to the *columnList*.
(Inherited from [SqlSet<TResult>][1]) | | [OrderBy(String)][71] | Sorts the elements of the set according to the *columnList*.
(Inherited from [SqlSet<TResult>][1]) | | [Refresh][72] | Sets all column members of *entity* to their most current persisted value. | | [RefreshAsync][73] | Sets all column members of *entity* to their most current persisted value. | | [Remove][74] | Executes a DELETE command for the specified *entity*. | | [RemoveAsync][75] | Executes a DELETE command for the specified *entity*. | | [RemoveKey][76] | Executes a DELETE command for the entity whose primary key matches the *id* parameter. | | [RemoveKeyAsync][77] | Executes a DELETE command for the entity whose primary key matches the *id* parameter. | | [RemoveRange(IEnumerable<TEntity>)][78] | Executes DELETE commands for the specified *entities*. | | [RemoveRange(TEntity[])][79] | Executes DELETE commands for the specified *entities*. | | [RemoveRangeAsync(TEntity[])][80] | Executes DELETE commands for the specified *entities*. | | [RemoveRangeAsync(IEnumerable<TEntity>, CancellationToken)][81] | Executes DELETE commands for the specified *entities*. | | [Select(OperatorStringHandler, Type)][82] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select(String, Type)][83] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(OperatorStringHandler)][84] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(String)][85] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(OperatorStringHandler, Func<DbDataReader, TResult>)][86] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Select<TResult>(String, Func<DbDataReader, TResult>)][87] | Projects each element of the set into a new form.
(Inherited from [SqlSet][4]) | | [Single()][88] | The single element of the set.
(Inherited from [SqlSet<TResult>][1]) | | [Single(OperatorStringHandler)][89] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists.
(Inherited from [SqlSet<TResult>][1]) | | [Single(String)][90] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists.
(Inherited from [SqlSet<TResult>][1]) | | [SingleAsync(CancellationToken)][91] | The single element of the set.
(Inherited from [SqlSet<TResult>][1]) | | [SingleAsync(OperatorStringHandler, CancellationToken)][92] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists.
(Inherited from [SqlSet<TResult>][1]) | | [SingleAsync(String, CancellationToken)][93] | Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists.
(Inherited from [SqlSet<TResult>][1]) | | [SingleOrDefault()][94] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set.
(Inherited from [SqlSet<TResult>][1]) | | [SingleOrDefault(OperatorStringHandler)][95] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition.
(Inherited from [SqlSet<TResult>][1]) | | [SingleOrDefault(String)][96] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition.
(Inherited from [SqlSet<TResult>][1]) | | [SingleOrDefaultAsync(CancellationToken)][97] | Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set.
(Inherited from [SqlSet<TResult>][1]) | | [SingleOrDefaultAsync(OperatorStringHandler, CancellationToken)][98] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition.
(Inherited from [SqlSet<TResult>][1]) | | [SingleOrDefaultAsync(String, CancellationToken)][99] | Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition.
(Inherited from [SqlSet<TResult>][1]) | | [Skip][100] | Bypasses a specified number of elements in the set and then returns the remaining elements.
(Inherited from [SqlSet<TResult>][1]) | | [Take][101] | Returns a specified number of contiguous elements from the start of the set.
(Inherited from [SqlSet<TResult>][1]) | | [ToArray][102] | Creates an array from the set.
(Inherited from [SqlSet<TResult>][1]) | | [ToArrayAsync][103] | Creates an array from the set.
(Inherited from [SqlSet<TResult>][1]) | | [ToList][104] | Creates a List<TResult> from the set.
(Inherited from [SqlSet<TResult>][1]) | | [ToListAsync][105] | Creates a List<TResult> from the set.
(Inherited from [SqlSet<TResult>][1]) | | [ToString][106] | Returns the SQL query of the set.
(Inherited from [SqlSet][4]) | | [Update(TEntity)][107] | Executes an UPDATE command for the specified *entity*. | | [Update(TEntity, Object)][108] | Executes an UPDATE command for the specified *entity*. | | [UpdateAsync(TEntity, CancellationToken)][109] | Executes an UPDATE command for the specified *entity*. | | [UpdateAsync(TEntity, Object, CancellationToken)][110] | Executes an UPDATE command for the specified *entity*. | | [UpdateRange(IEnumerable<TEntity>)][111] | Executes UPDATE commands for the specified *entities*. | | [UpdateRange(TEntity[])][112] | Executes UPDATE commands for the specified *entities*. | | [UpdateRangeAsync(TEntity[])][113] | Executes UPDATE commands for the specified *entities*. | | [UpdateRangeAsync(IEnumerable<TEntity>, CancellationToken)][114] | Executes UPDATE commands for the specified *entities*. | | [Where(OperatorStringHandler)][115] | Filters the set based on a predicate.
(Inherited from [SqlSet<TResult>][1]) | | [Where(String)][116] | Filters the set based on a predicate.
(Inherited from [SqlSet<TResult>][1]) | See Also -------- #### Reference [DbExtensions Namespace][5] [1]: ../SqlSet_1/README.md [2]: ../Database/Table__1.md [3]: https://learn.microsoft.com/dotnet/api/system.object [4]: ../SqlSet/README.md [5]: ../README.md [6]: ../SqlSet/Database.md [7]: ../Database/README.md [8]: Name.md [9]: ../SqlSet/ResultType.md [10]: Add.md [11]: AddAsync.md [12]: AddRange.md [13]: AddRange_1.md [14]: AddRangeAsync_1.md [15]: AddRangeAsync.md [16]: ../SqlSet/All.md [17]: ../SqlSet/All_1.md [18]: ../SqlSet/AllAsync.md [19]: ../SqlSet/AllAsync_1.md [20]: ../SqlSet/Any.md [21]: ../SqlSet/Any_1.md [22]: ../SqlSet/Any_2.md [23]: ../SqlSet/AnyAsync_2.md [24]: ../SqlSet/AnyAsync.md [25]: ../SqlSet/AnyAsync_1.md [26]: ../SqlSet_1/AsAsyncEnumerable.md [27]: ../SqlSet_1/AsEnumerable.md [28]: ../SqlSet/Cast.md [29]: ../SqlSet/Cast__1.md [30]: ../SqlSet/Contains.md [31]: ../SqlSet_1/Contains.md [32]: ../SqlSet/ContainsAsync.md [33]: ../SqlSet_1/ContainsAsync.md [34]: ../SqlSet/ContainsKey.md [35]: ../SqlSet/ContainsKeyAsync.md [36]: ../SqlSet/Count.md [37]: ../SqlSet/Count_1.md [38]: ../SqlSet/Count_2.md [39]: ../SqlSet/CountAsync_2.md [40]: ../SqlSet/CountAsync.md [41]: ../SqlSet/CountAsync_1.md [42]: ../SqlSet_1/Find.md [43]: ../SqlSet_1/FindAsync.md [44]: ../SqlSet_1/First.md [45]: ../SqlSet_1/First_1.md [46]: ../SqlSet_1/First_2.md [47]: ../SqlSet_1/FirstAsync_2.md [48]: ../SqlSet_1/FirstAsync.md [49]: ../SqlSet_1/FirstAsync_1.md [50]: ../SqlSet_1/FirstOrDefault.md [51]: ../SqlSet_1/FirstOrDefault_1.md [52]: ../SqlSet_1/FirstOrDefault_2.md [53]: ../SqlSet_1/FirstOrDefaultAsync_2.md [54]: ../SqlSet_1/FirstOrDefaultAsync.md [55]: ../SqlSet_1/FirstOrDefaultAsync_1.md [56]: ../SqlSet_1/GetAsyncEnumerator.md [57]: ../SqlSet/GetDefiningQuery.md [58]: ../SqlSet_1/GetEnumerator.md [59]: ../SqlSet_1/Include_1.md [60]: ../SqlSet_1/Include.md [61]: ../SqlSet_1/IncludeMany.md [62]: ../SqlSet_1/IncludeMany__1.md [63]: ../SqlSet/LongCount.md [64]: https://learn.microsoft.com/dotnet/api/system.int64 [65]: ../SqlSet/LongCount_1.md [66]: ../SqlSet/LongCount_2.md [67]: ../SqlSet/LongCountAsync_2.md [68]: ../SqlSet/LongCountAsync.md [69]: ../SqlSet/LongCountAsync_1.md [70]: ../SqlSet_1/OrderBy.md [71]: ../SqlSet_1/OrderBy_1.md [72]: Refresh.md [73]: RefreshAsync.md [74]: Remove.md [75]: RemoveAsync.md [76]: RemoveKey.md [77]: RemoveKeyAsync.md [78]: RemoveRange.md [79]: RemoveRange_1.md [80]: RemoveRangeAsync_1.md [81]: RemoveRangeAsync.md [82]: ../SqlSet/Select_1.md [83]: ../SqlSet/Select_3.md [84]: ../SqlSet/Select__1.md [85]: ../SqlSet/Select__1_2.md [86]: ../SqlSet/Select__1_1.md [87]: ../SqlSet/Select__1_3.md [88]: ../SqlSet_1/Single.md [89]: ../SqlSet_1/Single_1.md [90]: ../SqlSet_1/Single_2.md [91]: ../SqlSet_1/SingleAsync_2.md [92]: ../SqlSet_1/SingleAsync.md [93]: ../SqlSet_1/SingleAsync_1.md [94]: ../SqlSet_1/SingleOrDefault.md [95]: ../SqlSet_1/SingleOrDefault_1.md [96]: ../SqlSet_1/SingleOrDefault_2.md [97]: ../SqlSet_1/SingleOrDefaultAsync_2.md [98]: ../SqlSet_1/SingleOrDefaultAsync.md [99]: ../SqlSet_1/SingleOrDefaultAsync_1.md [100]: ../SqlSet_1/Skip.md [101]: ../SqlSet_1/Take.md [102]: ../SqlSet_1/ToArray.md [103]: ../SqlSet_1/ToArrayAsync.md [104]: ../SqlSet_1/ToList.md [105]: ../SqlSet_1/ToListAsync.md [106]: ../SqlSet/ToString.md [107]: Update.md [108]: Update_1.md [109]: UpdateAsync_1.md [110]: UpdateAsync.md [111]: UpdateRange.md [112]: UpdateRange_1.md [113]: UpdateRangeAsync_1.md [114]: UpdateRangeAsync.md [115]: ../SqlSet_1/Where.md [116]: ../SqlSet_1/Where_1.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/Refresh.md ================================================ SqlTable<TEntity>.Refresh Method =================================== Sets all column members of *entity* to their most current persisted value. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public void Refresh( TEntity entity ) ``` #### Parameters ##### *entity*  [TEntity][2] The entity to refresh. See Also -------- #### Reference [SqlTable<TEntity> Class][2] [DbExtensions Namespace][1] [1]: ../README.md [2]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/RefreshAsync.md ================================================ SqlTable<TEntity>.RefreshAsync Method ======================================== Sets all column members of *entity* to their most current persisted value. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask RefreshAsync( TEntity entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [TEntity][2] The entity to refresh. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5] See Also -------- #### Reference [SqlTable<TEntity> Class][2] [DbExtensions Namespace][1] [1]: ../README.md [2]: README.md [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask ================================================ FILE: docs/api/DbExtensions/SqlTable_1/Remove.md ================================================ SqlTable<TEntity>.Remove Method ================================== Executes a DELETE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool Remove( TEntity entity ) ``` #### Parameters ##### *entity*  [TEntity][2] The entity whose DELETE command is to be executed. #### Return Value [Boolean][3] `true` if *entity* is deleted; otherwise, `false`. See Also -------- #### Reference [SqlTable<TEntity> Class][2] [DbExtensions Namespace][1] [1]: ../README.md [2]: README.md [3]: https://learn.microsoft.com/dotnet/api/system.boolean ================================================ FILE: docs/api/DbExtensions/SqlTable_1/RemoveAsync.md ================================================ SqlTable<TEntity>.RemoveAsync Method ======================================= Executes a DELETE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask RemoveAsync( TEntity entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [TEntity][2] The entity whose DELETE command is to be executed. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[Boolean][6]> `true` if *entity* is deleted; otherwise, `false`. See Also -------- #### Reference [SqlTable<TEntity> Class][2] [DbExtensions Namespace][1] [1]: ../README.md [2]: README.md [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.boolean ================================================ FILE: docs/api/DbExtensions/SqlTable_1/RemoveKey.md ================================================ SqlTable<TEntity>.RemoveKey Method ===================================== Executes a DELETE command for the entity whose primary key matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public bool RemoveKey( Object id ) ``` #### Parameters ##### *id*  [Object][2] The primary key value. #### Return Value [Boolean][3] `true` if a record that matches *id* was found and deleted; otherwise, `false`. See Also -------- #### Reference [SqlTable<TEntity> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.boolean [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/RemoveKeyAsync.md ================================================ SqlTable<TEntity>.RemoveKeyAsync Method ========================================== Executes a DELETE command for the entity whose primary key matches the *id* parameter. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public ValueTask RemoveKeyAsync( Object id, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *id*  [Object][2] The primary key value. ##### *cancellationToken*  [CancellationToken][3]  (Optional) The [CancellationToken][3] to monitor for cancellation requests. The default is [None][4]. #### Return Value [ValueTask][5]<[Boolean][6]> `true` if a record that matches *id* was found and deleted; otherwise, `false`. See Also -------- #### Reference [SqlTable<TEntity> Class][7] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.object [3]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [5]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask-1 [6]: https://learn.microsoft.com/dotnet/api/system.boolean [7]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/RemoveRange.md ================================================ SqlTable<TEntity>.RemoveRange(IEnumerable<TEntity>) Method ================================================================ Executes DELETE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------- | ------------------------------------------------------ | | **RemoveRange(IEnumerable<TEntity>)** | Executes DELETE commands for the specified *entities*. | | [RemoveRange(TEntity[])][2] | Executes DELETE commands for the specified *entities*. | Syntax ------ ```csharp public void RemoveRange( IEnumerable entities ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[TEntity][4]> The entities whose DELETE commands are to be executed. See Also -------- #### Reference [SqlTable<TEntity> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: RemoveRange_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/RemoveRangeAsync.md ================================================ SqlTable<TEntity>.RemoveRangeAsync(IEnumerable<TEntity>, CancellationToken) Method ======================================================================================== Executes DELETE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------- | ------------------------------------------------------ | | [RemoveRangeAsync(TEntity[])][2] | Executes DELETE commands for the specified *entities*. | | **RemoveRangeAsync(IEnumerable<TEntity>, CancellationToken)** | Executes DELETE commands for the specified *entities*. | Syntax ------ ```csharp public ValueTask RemoveRangeAsync( IEnumerable entities, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[TEntity][4]> The entities whose DELETE commands are to be executed. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7] See Also -------- #### Reference [SqlTable<TEntity> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: RemoveRangeAsync_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask ================================================ FILE: docs/api/DbExtensions/SqlTable_1/RemoveRangeAsync_1.md ================================================ SqlTable<TEntity>.RemoveRangeAsync(TEntity[]) Method ======================================================= Executes DELETE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------------------------------- | ------------------------------------------------------ | | **RemoveRangeAsync(TEntity[])** | Executes DELETE commands for the specified *entities*. | | [RemoveRangeAsync(IEnumerable<TEntity>, CancellationToken)][2] | Executes DELETE commands for the specified *entities*. | Syntax ------ ```csharp public ValueTask RemoveRangeAsync( params TEntity[] entities ) ``` #### Parameters ##### *entities*  [TEntity][3][] The entities whose DELETE commands are to be executed. #### Return Value [ValueTask][4] See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: RemoveRangeAsync.md [3]: README.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask ================================================ FILE: docs/api/DbExtensions/SqlTable_1/RemoveRange_1.md ================================================ SqlTable<TEntity>.RemoveRange(TEntity[]) Method ================================================== Executes DELETE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------- | ------------------------------------------------------ | | [RemoveRange(IEnumerable<TEntity>)][2] | Executes DELETE commands for the specified *entities*. | | **RemoveRange(TEntity[])** | Executes DELETE commands for the specified *entities*. | Syntax ------ ```csharp public void RemoveRange( params TEntity[] entities ) ``` #### Parameters ##### *entities*  [TEntity][3][] The entities whose DELETE commands are to be executed. See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: RemoveRange.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/Update.md ================================================ SqlTable<TEntity>.Update(TEntity) Method =========================================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------- | ------------------------------------------------------ | | **Update(TEntity)** | Executes an UPDATE command for the specified *entity*. | | [Update(TEntity, Object)][2] | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public void Update( TEntity entity ) ``` #### Parameters ##### *entity*  [TEntity][3] The entity whose UPDATE command is to be executed. See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: Update_1.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/UpdateAsync.md ================================================ SqlTable<TEntity>.UpdateAsync(TEntity, Object, CancellationToken) Method =========================================================================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------------------------------- | ------------------------------------------------------ | | [UpdateAsync(TEntity, CancellationToken)][2] | Executes an UPDATE command for the specified *entity*. | | **UpdateAsync(TEntity, Object, CancellationToken)** | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public ValueTask UpdateAsync( TEntity entity, Object? originalId, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [TEntity][3] The entity whose UPDATE command is to be executed. ##### *originalId*  [Object][4] The original primary key value. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7] Remarks ------- This overload is helpful when the entity uses an assigned primary key. See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateAsync_1.md [3]: README.md [4]: https://learn.microsoft.com/dotnet/api/system.object [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask ================================================ FILE: docs/api/DbExtensions/SqlTable_1/UpdateAsync_1.md ================================================ SqlTable<TEntity>.UpdateAsync(TEntity, CancellationToken) Method =================================================================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------- | ------------------------------------------------------ | | **UpdateAsync(TEntity, CancellationToken)** | Executes an UPDATE command for the specified *entity*. | | [UpdateAsync(TEntity, Object, CancellationToken)][2] | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public ValueTask UpdateAsync( TEntity entity, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entity*  [TEntity][3] The entity whose UPDATE command is to be executed. ##### *cancellationToken*  [CancellationToken][4]  (Optional) The [CancellationToken][4] to monitor for cancellation requests. The default is [None][5]. #### Return Value [ValueTask][6] See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateAsync.md [3]: README.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [6]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask ================================================ FILE: docs/api/DbExtensions/SqlTable_1/UpdateRange.md ================================================ SqlTable<TEntity>.UpdateRange(IEnumerable<TEntity>) Method ================================================================ Executes UPDATE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------- | ------------------------------------------------------ | | **UpdateRange(IEnumerable<TEntity>)** | Executes UPDATE commands for the specified *entities*. | | [UpdateRange(TEntity[])][2] | Executes UPDATE commands for the specified *entities*. | Syntax ------ ```csharp public void UpdateRange( IEnumerable entities ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[TEntity][4]> The entities whose UPDATE commands are to be executed. See Also -------- #### Reference [SqlTable<TEntity> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateRange_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/UpdateRangeAsync.md ================================================ SqlTable<TEntity>.UpdateRangeAsync(IEnumerable<TEntity>, CancellationToken) Method ======================================================================================== Executes UPDATE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ---------------------------------------------------------------- | ------------------------------------------------------ | | [UpdateRangeAsync(TEntity[])][2] | Executes UPDATE commands for the specified *entities*. | | **UpdateRangeAsync(IEnumerable<TEntity>, CancellationToken)** | Executes UPDATE commands for the specified *entities*. | Syntax ------ ```csharp public ValueTask UpdateRangeAsync( IEnumerable entities, CancellationToken cancellationToken = default ) ``` #### Parameters ##### *entities*  [IEnumerable][3]<[TEntity][4]> The entities whose UPDATE commands are to be executed. ##### *cancellationToken*  [CancellationToken][5]  (Optional) The [CancellationToken][5] to monitor for cancellation requests. The default is [None][6]. #### Return Value [ValueTask][7] See Also -------- #### Reference [SqlTable<TEntity> Class][4] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateRangeAsync_1.md [3]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1 [4]: README.md [5]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken [6]: https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken.none [7]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask ================================================ FILE: docs/api/DbExtensions/SqlTable_1/UpdateRangeAsync_1.md ================================================ SqlTable<TEntity>.UpdateRangeAsync(TEntity[]) Method ======================================================= Executes UPDATE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------------------------------- | ------------------------------------------------------ | | **UpdateRangeAsync(TEntity[])** | Executes UPDATE commands for the specified *entities*. | | [UpdateRangeAsync(IEnumerable<TEntity>, CancellationToken)][2] | Executes UPDATE commands for the specified *entities*. | Syntax ------ ```csharp public ValueTask UpdateRangeAsync( params TEntity[] entities ) ``` #### Parameters ##### *entities*  [TEntity][3][] The entities whose UPDATE commands are to be executed. #### Return Value [ValueTask][4] See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateRangeAsync.md [3]: README.md [4]: https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask ================================================ FILE: docs/api/DbExtensions/SqlTable_1/UpdateRange_1.md ================================================ SqlTable<TEntity>.UpdateRange(TEntity[]) Method ================================================== Executes UPDATE commands for the specified *entities*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | ----------------------------------------- | ------------------------------------------------------ | | [UpdateRange(IEnumerable<TEntity>)][2] | Executes UPDATE commands for the specified *entities*. | | **UpdateRange(TEntity[])** | Executes UPDATE commands for the specified *entities*. | Syntax ------ ```csharp public void UpdateRange( params TEntity[] entities ) ``` #### Parameters ##### *entities*  [TEntity][3][] The entities whose UPDATE commands are to be executed. See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: UpdateRange.md [3]: README.md ================================================ FILE: docs/api/DbExtensions/SqlTable_1/Update_1.md ================================================ SqlTable<TEntity>.Update(TEntity, Object) Method =================================================== Executes an UPDATE command for the specified *entity*. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Overloads --------- | Name | Description | | --------------------------- | ------------------------------------------------------ | | [Update(TEntity)][2] | Executes an UPDATE command for the specified *entity*. | | **Update(TEntity, Object)** | Executes an UPDATE command for the specified *entity*. | Syntax ------ ```csharp public void Update( TEntity entity, Object? originalId ) ``` #### Parameters ##### *entity*  [TEntity][3] The entity whose UPDATE command is to be executed. ##### *originalId*  [Object][4] The original primary key value. Remarks ------- This overload is helpful when the entity uses an assigned primary key. See Also -------- #### Reference [SqlTable<TEntity> Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: Update.md [3]: README.md [4]: https://learn.microsoft.com/dotnet/api/system.object ================================================ FILE: docs/api/DbExtensions/TableAttribute/Name.md ================================================ TableAttribute.Name Property ============================ Gets or sets the name of the table or view. **Namespace:** [DbExtensions][1] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public string? Name { get; set; } ``` #### Property Value [String][2] See Also -------- #### Reference [TableAttribute Class][3] [DbExtensions Namespace][1] [1]: ../README.md [2]: https://learn.microsoft.com/dotnet/api/system.string [3]: README.md ================================================ FILE: docs/api/DbExtensions/TableAttribute/README.md ================================================ TableAttribute Class ==================== Designates a class as an entity class that is associated with a database table. Inheritance Hierarchy --------------------- [System.Object][1]   [System.Attribute][2]     **DbExtensions.TableAttribute** **Namespace:** [DbExtensions][3] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public sealed class TableAttribute : Attribute ``` The **TableAttribute** type exposes the following members. Constructors ------------ | Name | Description | | ------------------- | ---------------------------------------------------------- | | [TableAttribute][4] | Initializes a new instance of the **TableAttribute** class | Properties ---------- | Name | Description | | --------- | ------------------------------------------- | | [Name][5] | Gets or sets the name of the table or view. | See Also -------- #### Reference [DbExtensions Namespace][3] [1]: https://learn.microsoft.com/dotnet/api/system.object [2]: https://learn.microsoft.com/dotnet/api/system.attribute [3]: ../README.md [4]: _ctor.md [5]: Name.md ================================================ FILE: docs/api/DbExtensions/TableAttribute/_ctor.md ================================================ TableAttribute Constructor ========================== Initializes a new instance of the [TableAttribute][1] class **Namespace:** [DbExtensions][2] **Assembly:** DbExtensions.dll Syntax ------ ```csharp public TableAttribute() ``` See Also -------- #### Reference [TableAttribute Class][1] [DbExtensions Namespace][2] [1]: README.md [2]: ../README.md ================================================ FILE: docs/api/README.md ================================================ DbExtensions Namespaces ======================= Namespaces ---------- | Namespace | Description | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [DbExtensions][1] | DbExtensions is a data-access framework with a strong focus on query composition, granularity and code aesthetics. [Database][2] is the entry point of the [DbExtensions][1] API. | [1]: DbExtensions/README.md [2]: DbExtensions/Database/README.md ================================================ FILE: samples/App/App.config ================================================  ================================================ FILE: samples/App/Program.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Configuration; using System.Data.Common; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text.RegularExpressions; using DbExtensions; namespace Samples { using static Console; class Program { readonly string _samplesPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "..", "..", ".."); static void Main() { DbProviderFactories.RegisterFactory("Microsoft.Data.SqlClient", Microsoft.Data.SqlClient.SqlClientFactory.Instance); DbProviderFactories.RegisterFactory("MySql.Data.MySqlClient", MySql.Data.MySqlClient.MySqlClientFactory.Instance); DbProviderFactories.RegisterFactory("System.Data.SQLite", System.Data.SQLite.SQLiteFactory.Instance); new Program().Run(); } void Run() { WriteLine("DbExtensions Sample Runner"); WriteLine("=========================="); var connectionStrings = ConfigurationManager.ConnectionStrings .Cast() // Only connection strings defined in this application config file .Where(c => c.ElementInformation.Source != null && c.ElementInformation.Source.EndsWith("dll.config", StringComparison.OrdinalIgnoreCase)) .ToArray(); var connIndex = GetArrayOption(connectionStrings.Select(c => c.Name).ToArray(), "Select a connection string (or Enter to select the first one):"); var connSettings = connectionStrings[connIndex]; var provider = DbProviderFactories.GetFactory(connSettings.ProviderName); WriteLine(); WriteLine("Provider: {0}", provider.GetType().AssemblyQualifiedName); WriteLine(); WriteLine("Connecting..."); try { var db = new Database(connSettings.ConnectionString, connSettings.ProviderName); using (db.EnsureConnectionOpen()) { WriteLine("Server Version: {0}", ((DbConnection)db.Connection).ServerVersion); } } catch (Exception ex) { WriteError(ex, fatal: true); return; } var samplesLangs = GetSamplesLanguages(); var samplesLangIndex = GetArrayOption(samplesLangs, "Select the samples language (or Enter):"); var samplesLanguage = samplesLangs[samplesLangIndex]; object[] samples; try { samples = GetSamples(samplesLanguage, connSettings).ToArray(); } catch (Exception ex) { WriteError(ex, fatal: true); return; } var samplesOptions = (from s in samples let name = s.GetType().Name let friendlyName = name.Substring(0, name.Length - "Samples".Length) select friendlyName) .Append("All") .ToArray(); var samplesIndex = GetArrayOption(samplesOptions, "Select the samples category (or Enter to run all):", samplesOptions.Length - 1); var selectedSamples = (samplesIndex == samplesOptions.Length - 1) ? samples : [samples[samplesIndex]]; var continueOnErrorOptions = new[] { "Yes", "No" }; var continueOnError = GetArrayOption(continueOnErrorOptions, "Continue on Error:") == 0; WriteLine(); WriteLine("Press key to begin..."); ReadKey(); for (int i = 0; i < selectedSamples.Length; i++) { var sampl = selectedSamples[i]; RunSamples(sampl, continueOnError); if (sampl is IDisposable disp) { disp.Dispose(); } WriteLine(); WriteLine((i == selectedSamples.Length - 1) ? "Press key to exit..." : "Press key to continue..."); ReadKey(); } } string[] GetSamplesLanguages() { var appDir = AppDomain.CurrentDomain.BaseDirectory .Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries) .Reverse() .Skip(3) .First(); var projectsDir = Directory .GetDirectories(_samplesPath, "*", SearchOption.TopDirectoryOnly) .Select(s => s.Split(Path.DirectorySeparatorChar).Last()) .Where(s => !s.Equals(appDir)) .ToArray(); return projectsDir; } IEnumerable GetSamples(string language, ConnectionStringSettings connSettings) { var projectDir = Path.Combine(_samplesPath, language); var projectFile = Directory.GetFiles(projectDir, String.Format("*.{0}proj", Regex.Replace(language, "[a-z]", ""))) .FirstOrDefault() ?? throw new InvalidOperationException("Project file not found."); var projectFileName = projectFile.Split(Path.DirectorySeparatorChar).Last(); var assemblyName = String.Join(".", projectFileName.Split('.').Reverse().Skip(1).Reverse()); var assemblyDir = Directory.GetDirectories(Path.Combine(projectDir, "bin", "Debug"), "net*").First(); var assemblyPath = new Uri(Path.Combine(assemblyDir, assemblyName + ".dll")).LocalPath; var samplesAssembly = Assembly.LoadFrom(assemblyPath); var dbType = samplesAssembly.GetTypes() .Where(t => typeof(Database).IsAssignableFrom(t)) .Single(); var db = (Database)Activator.CreateInstance(dbType, connSettings.ConnectionString, connSettings.ProviderName); db.Configuration.Log = Out; return from t in samplesAssembly.GetTypes() where t.IsPublic && t.Name.EndsWith("Samples") let parameters = t.GetConstructors().First().GetParameters() let args = from p in parameters select (typeof(Database).IsAssignableFrom(p.ParameterType) ? db : p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null) select Activator.CreateInstance(t, args.ToArray()); } static void RunSamples(object samples, bool continueOnError) { var samplesType = samples.GetType(); var isDisposable = samples is IDisposable; var methods = samplesType .GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) .ToList(); for (int i = 0; i < methods.Count; i++) { var method = methods[i]; if (isDisposable && method.Name == "Dispose") { continue; } WriteLine(); WriteLine(method.Name); Write(new string('=', method.Name.Length)); WriteLine(); object returnValue = null; if (method.ReturnType == typeof(void)) { var runSample = (Action)Delegate.CreateDelegate(typeof(Action), samples, method); if (continueOnError) { try { runSample(); } catch (Exception ex) { WriteError(ex); continue; } } else { runSample(); } } else { void runSample() { returnValue = Expression.Lambda>( Expression.Convert( Expression.Call(Expression.Constant(samples), method) , typeof(object) ) ).Compile()(); if (returnValue is IEnumerable ienum) { returnValue = ienum.Cast().ToArray(); } } if (continueOnError) { try { runSample(); } catch (Exception ex) { WriteError(ex); continue; } } else { runSample(); } } if (returnValue != null) { WriteLine(); if (returnValue is SqlBuilder sql) { WriteLine(returnValue); for (int j = 0; j < sql.ParameterValues.Count; j++) { var value = sql.ParameterValues[j]; var type = value?.GetType(); WriteLine("-- {0}: {1} [{2}]", j, type, value); } } else { var color = ForegroundColor; ForegroundColor = ConsoleColor.DarkGray; ObjectDumper.Write(returnValue, 1, Out); ForegroundColor = color; } } } } static int GetArrayOption(T[] options, string title, int defaultOption = 0) { var firstTry = true; var index = -1; var left = CursorLeft; while (index < 0 || index >= options.Length) { if (!firstTry) { WriteLine(); } firstTry = false; WriteLine(); WriteLine(title); for (int i = 0; i < options.Length; i++) { if (i > 0) { Write(", "); } Write("[{0}] {1}", i + 1, options[i]); } Write(": "); left = CursorLeft; var key = ReadKey(); if (key.Key == ConsoleKey.Enter) { index = defaultOption; } else { try { index = Int32.Parse(key.KeyChar.ToString()) - 1; } catch (Exception) { } } } var prevColor = ForegroundColor; ForegroundColor = ConsoleColor.Green; CursorLeft = left; Write(options[index]); WriteLine(); ForegroundColor = prevColor; return index; } static void WriteError(Exception ex, bool fatal = false) { var prevColor = ForegroundColor; ForegroundColor = ConsoleColor.Red; WriteLine(ex.Message); ForegroundColor = prevColor; WriteLine(); WriteLine((fatal) ? "Press key to exit..." : "Press key to continue..."); ReadKey(); } } } ================================================ FILE: samples/App/Samples.App.csproj ================================================  Exe net8.0 12 Always PreserveNewest Northwind.mdf Always ================================================ FILE: samples/App/Utilities/ObjectDumper-LICENSE.txt ================================================ MICROSOFT LIMITED PUBLIC LICENSE version 1.1 This license governs use of code marked as “sample” or “example” available on this web site without a license agreement, as provided under the section above titled “NOTICE SPECIFIC TO SOFTWARE AVAILABLE ON THIS WEB SITE.” If you use such code (the “software”), you accept this license. If you do not accept the license, do not use the software. 1. Definitions The terms “reproduce,” “reproduction,” “derivative works,” and “distribution” have the same meaning here as under U.S. copyright law. A “contribution” is the original software, or any additions or changes to the software. A “contributor” is any person that distributes its contribution under this license. “Licensed patents” are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights (A) Copyright Grant - Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. (B) Patent Grant - Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations (A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. (E) The software is licensed “as-is.” You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. (F) Platform Limitation - The licenses granted in sections 2(A) and 2(B) extend only to the software or derivative works that you create that run directly on a Microsoft Windows operating system product, Microsoft run-time technology (such as the .NET Framework or Silverlight), or Microsoft application platform (such as Microsoft Office or Microsoft Dynamics). ================================================ FILE: samples/App/Utilities/ObjectDumper.cs ================================================ // Copyright (C) Microsoft Corporation. All rights reserved. // See ObjectDumper-LICENSE.txt for license information. using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.Reflection; public class ObjectDumper { public static void Write(object element) { Write(element, 0); } public static void Write(object element, int depth) { Write(element, depth, Console.Out); } public static void Write(object element, int depth, TextWriter log) { ObjectDumper dumper = new ObjectDumper(depth); dumper.writer = log; dumper.WriteObject(null, element); } TextWriter writer; int pos; int level; int depth; private ObjectDumper(int depth) { this.depth = depth; } private void Write(string s) { if (s != null) { writer.Write(s); pos += s.Length; } } private void WriteIndent() { for (int i = 0; i < level; i++) writer.Write(" "); } private void WriteLine() { writer.WriteLine(); pos = 0; } private void WriteTab() { Write(" "); while (pos % 8 != 0) Write(" "); } private void WriteObject(string prefix, object element) { if (element == null || element is ValueType || element is string) { WriteIndent(); Write(prefix); WriteValue(element); WriteLine(); } else { IEnumerable enumerableElement = element as IEnumerable; if (enumerableElement != null) { foreach (object item in enumerableElement) { if (item is IEnumerable && !(item is string)) { WriteIndent(); Write(prefix); Write("..."); WriteLine(); if (level < depth) { level++; WriteObject(prefix, item); level--; } } else { WriteObject(prefix, item); } } } else { MemberInfo[] members = element.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance); WriteIndent(); Write(prefix); bool propWritten = false; foreach (MemberInfo m in members) { FieldInfo f = m as FieldInfo; PropertyInfo p = m as PropertyInfo; if (f != null || p != null) { if (propWritten) { WriteTab(); } else { propWritten = true; } Write(m.Name); Write("="); Type t = f != null ? f.FieldType : p.PropertyType; if (t.IsValueType || t == typeof(string)) { WriteValue(f != null ? f.GetValue(element) : p.GetValue(element, null)); } else { if (typeof(IEnumerable).IsAssignableFrom(t)) { Write("..."); } else { Write("{ }"); } } } } if (propWritten) WriteLine(); if (level < depth) { foreach (MemberInfo m in members) { FieldInfo f = m as FieldInfo; PropertyInfo p = m as PropertyInfo; if (f != null || p != null) { Type t = f != null ? f.FieldType : p.PropertyType; if (!(t.IsValueType || t == typeof(string))) { object value = f != null ? f.GetValue(element) : p.GetValue(element, null); if (value != null) { level++; WriteObject(m.Name + ": ", value); level--; } } } } } } } } private void WriteValue(object o) { if (o == null) { Write("null"); } else if (o is DateTime) { Write(((DateTime)o).ToShortDateString()); } else if (o is ValueType || o is string) { Write(o.ToString()); } else if (o is IEnumerable) { Write("..."); } else { Write("{ }"); } } } ================================================ FILE: samples/CSharp/Database.Annotated.cs ================================================ using System; using System.Collections.Generic; using Samples.CSharp.Northwind; namespace Samples.CSharp { public class DatabaseAnnotatedSamples { readonly NorthwindDatabase db; public DatabaseAnnotatedSamples(NorthwindDatabase db) { this.db = db; } public IEnumerable IncludeManyToOne() { return db.Products .Include(p => p.Category) .Include(p => p.Supplier) .Take(3) .AsEnumerable(); } public IEnumerable IncludeManyToOneNested() { return db.EmployeeTerritories .Include(p => p.Territory.Region) .Take(3) .AsEnumerable(); } public Region IncludeOneToMany() { return db.Regions .IncludeMany(p => p.Territories) .First(); } public bool ContainsKey() { return db.Products.ContainsKey(1); } public Product Find() { return db.Products.Find(1); } public void Transactions_AdoNet() { using var tx = db.EnsureInTransaction(); // Connection is automatically opened if not open var order = new Order { CustomerID = "ALFKI", OrderDetails = { new OrderDetail { ProductID = 77, Quantity = 1 }, new OrderDetail { ProductID = 41, Quantity = 2 } } }; db.Orders.Add(order); order.Freight = 10m; db.Orders.Update(order); // The following line is not needed when cascade delete is configured on the database db.OrderDetails.RemoveRange(order.OrderDetails); db.Orders.Remove(order); tx.Commit(); // Connection is closed if wasn't open } } } ================================================ FILE: samples/CSharp/Database.Poco.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using DbExtensions; using Samples.CSharp.Northwind; namespace Samples.CSharp { public class DatabasePocoSamples { readonly Database db; public DatabasePocoSamples(Database db) { this.db = db; } public IEnumerable SelectWithManyToOne() { var query = SQL .SELECT("p.ProductID, p.ProductName, p.CategoryID, s.SupplierID, '' AS MissingProperty") ._("c.CategoryID AS Category$CategoryID, c.CategoryName AS Category$CategoryName") ._("s.SupplierID AS Supplier$SupplierID, s.CompanyName AS Supplier$CompanyName") .FROM("Products p") .LEFT_JOIN("Categories c ON p.CategoryID = c.CategoryID") .LEFT_JOIN("Suppliers s ON p.SupplierID = s.SupplierID") .WHERE($"p.ProductID < {3}"); return db.Map(query); } public IEnumerable SelectWithManyToOneNested() { var query = SQL .SELECT("et.EmployeeID, et.TerritoryID") ._("t.TerritoryID AS Territory$TerritoryID, t.TerritoryDescription AS Territory$TerritoryDescription, t.RegionID AS Territory$RegionID") ._("r.RegionID AS Territory$Region$RegionID, r.RegionDescription AS Territory$Region$RegionDescription") .FROM("EmployeeTerritories et") .LEFT_JOIN("Territories t ON et.TerritoryID = t.TerritoryID") .LEFT_JOIN("Region r ON t.RegionID = r.RegionID") .WHERE($"et.EmployeeID < {3}"); return db.Map(query); } public IEnumerable AnnonymousType() { var query = SQL .SELECT("p.ProductID, p.ProductName") .FROM("Products p") .WHERE($"p.ProductID < {3}"); return db.Map(query, r => new { ProductID = r.GetInt32(0), ProductName = r.GetStringOrNull(1) }); } public IEnumerable MappingCalculatedColumn() { var query = SQL .SELECT("p.ProductID, (p.UnitPrice * p.UnitsInStock) AS ValueInStock") .FROM("Products p") .WHERE($"p.ProductID < {3}") .ORDER_BY("ValueInStock"); return db.Map(query); } public MappingToConstructorArgumentsSample MappingToConstructorArguments() { var query = SQL .SELECT("1 AS '1'") ._("'http://example.com' AS Url$1") ._("15.5 AS Price$1, 'USD' AS Price$2"); return db.Map(query) .Single(); } public MappingToConstructorArgumentsSample MappingToConstructorArgumentsNested() { var query = SQL .SELECT("1 AS '1'") ._("'http://example.com' AS '2$1'") ._("15.5 AS '3$1', 'USD' AS '3$2'"); return db.Map(query) .Single(); } public IEnumerable Dynamic() { var query = SQL .SELECT("p.ProductID, p.ProductName, p.CategoryID, s.SupplierID") ._("c.CategoryID AS Category$CategoryID, c.CategoryName AS Category$CategoryName") ._("s.SupplierID AS Supplier$SupplierID, s.CompanyName AS Supplier$CompanyName") .FROM("Products p") .LEFT_JOIN("Categories c ON p.CategoryID = c.CategoryID") .LEFT_JOIN("Suppliers s ON p.SupplierID = s.SupplierID") .WHERE($"p.ProductID < {3}"); return db.Map(query); } } public class ProductWithStockValue : Product { public decimal ValueInStock { get; set; } } public class MappingToConstructorArgumentsSample { public int Id { get; private set; } public Uri Url { get; private set; } public Money? Price { get; private set; } public MappingToConstructorArgumentsSample(int id) { this.Id = id; } public MappingToConstructorArgumentsSample(int id, Uri url, Money? price) : this(id) { this.Url = url; this.Price = price; } } public struct Money { public readonly decimal Amount; public readonly string Currency; public Money(decimal amount, string currency) { this.Amount = amount; this.Currency = currency; } public override string ToString() { return this.Currency + this.Amount.ToString(); } } } ================================================ FILE: samples/CSharp/Northwind/Category.cs ================================================ using System; using System.Collections.ObjectModel; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "Categories")] public class Category { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int CategoryID { get; set; } [Column] public string CategoryName { get; set; } [Column] public string Description { get; set; } [Column] public byte[] Picture { get; set; } [Association(OtherKey = nameof(Product.CategoryID))] public Collection Products { get; } = new(); } } ================================================ FILE: samples/CSharp/Northwind/Customer.cs ================================================ using System; using System.Collections.ObjectModel; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "Customers")] public class Customer { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column] public string CompanyName { get; set; } [Column] public string ContactName { get; set; } [Column] public string ContactTitle { get; set; } [Column] public string Address { get; set; } [Column] public string City { get; set; } [Column] public string Region { get; set; } [Column] public string PostalCode { get; set; } [Column] public string Country { get; set; } [Column] public string Phone { get; set; } [Column] public string Fax { get; set; } [Association(OtherKey = nameof(CustomerCustomerDemo.CustomerID))] public Collection CustomerCustomerDemos { get; } = new(); [Association(OtherKey = nameof(Order.CustomerID))] public Collection Orders { get; } = new(); } } ================================================ FILE: samples/CSharp/Northwind/CustomerCustomerDemo.cs ================================================ using System; using DbExtensions; namespace Samples.CSharp.Northwind { [Table] public class CustomerCustomerDemo { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column(IsPrimaryKey = true)] public string CustomerTypeID { get; set; } [Association(ThisKey = nameof(CustomerTypeID))] public CustomerDemographic CustomerDemographic { get; set; } [Association(ThisKey = nameof(CustomerID))] public Customer Customer { get; set; } } } ================================================ FILE: samples/CSharp/Northwind/CustomerDemographic.cs ================================================ using System; using System.Collections.ObjectModel; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "CustomerDemographics")] public class CustomerDemographic { [Column(IsPrimaryKey = true)] public string CustomerTypeID { get; set; } [Column] public string CustomerDesc { get; set; } [Association(OtherKey = nameof(CustomerCustomerDemo.CustomerTypeID))] public Collection CustomerCustomerDemos { get; } = new(); } } ================================================ FILE: samples/CSharp/Northwind/Employee.cs ================================================ using System; using System.Collections.ObjectModel; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "Employees")] public class Employee { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int EmployeeID { get; set; } [Column] public string LastName { get; set; } [Column] public string FirstName { get; set; } [Column] public string Title { get; set; } [Column] public string TitleOfCourtesy { get; set; } [Column] public DateTime? BirthDate { get; set; } [Column] public DateTime? HireDate { get; set; } [Column] public string Address { get; set; } [Column] public string City { get; set; } [Column] public string Region { get; set; } [Column] public string PostalCode { get; set; } [Column] public string Country { get; set; } [Column] public string HomePhone { get; set; } [Column] public string Extension { get; set; } [Column] public byte[] Photo { get; set; } [Column] public string Notes { get; set; } [Column] public int? ReportsTo { get; set; } [Column] public string PhotoPath { get; set; } [Association(ThisKey = nameof(ReportsTo))] public Employee ReportsToEmployee { get; set; } [Association(OtherKey = nameof(Employee.ReportsTo))] public Collection Employees { get; } = new(); [Association(OtherKey = nameof(EmployeeTerritory.EmployeeID))] public Collection EmployeeTerritories { get; } = new(); [Association(OtherKey = nameof(Order.EmployeeID))] public Collection Orders { get; } = new(); } } ================================================ FILE: samples/CSharp/Northwind/EmployeeTerritory.cs ================================================ using System; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "EmployeeTerritories")] public class EmployeeTerritory { [Column(IsPrimaryKey = true)] public int EmployeeID { get; set; } [Column(IsPrimaryKey = true)] public string TerritoryID { get; set; } [Association(ThisKey = nameof(EmployeeID))] public Employee Employee { get; set; } [Association(ThisKey = nameof(TerritoryID))] public Territory Territory { get; set; } } } ================================================ FILE: samples/CSharp/Northwind/NorthwindDatabase.cs ================================================ using System; using DbExtensions; namespace Samples.CSharp.Northwind { public class NorthwindDatabase : Database { public SqlTable Products => Table(); public SqlTable Orders => Table(); public SqlTable OrderDetails => Table(); public SqlTable Employees => Table(); public SqlTable EmployeeTerritories => Table(); public SqlTable Regions => Table(); public NorthwindDatabase(string connectionString, string providerInvariantName) : base(connectionString, providerInvariantName) { } } } ================================================ FILE: samples/CSharp/Northwind/Order.cs ================================================ using System; using System.Collections.ObjectModel; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "Orders")] public class Order { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int OrderID { get; set; } [Column] public string CustomerID { get; set; } [Column] public int? EmployeeID { get; set; } [Column] public DateTime? OrderDate { get; set; } [Column] public DateTime? RequiredDate { get; set; } [Column] public DateTime? ShippedDate { get; set; } [Column] public int? ShipVia { get; set; } [Column] public decimal? Freight { get; set; } [Column] public string ShipName { get; set; } [Column] public string ShipAddress { get; set; } [Column] public string ShipCity { get; set; } [Column] public string ShipRegion { get; set; } [Column] public string ShipPostalCode { get; set; } [Column] public string ShipCountry { get; set; } [Association(OtherKey = nameof(OrderDetail.OrderID))] public Collection OrderDetails { get; } = new(); [Association(ThisKey = nameof(CustomerID))] public Customer Customer { get; set; } [Association(ThisKey = nameof(EmployeeID))] public Employee Employee { get; set; } [Association(ThisKey = nameof(ShipVia))] public Shipper Shipper { get; set; } } } ================================================ FILE: samples/CSharp/Northwind/OrderDetail.cs ================================================ using System; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "Order Details")] public class OrderDetail { [Column(IsPrimaryKey = true)] public int OrderID { get; set; } [Column(IsPrimaryKey = true)] public int ProductID { get; set; } [Column] public decimal UnitPrice { get; set; } [Column] public short Quantity { get; set; } [Column] public float Discount { get; set; } [Association(ThisKey = nameof(OrderID))] public Order Order { get; set; } [Association(ThisKey = nameof(ProductID))] public Product Product { get; set; } } } ================================================ FILE: samples/CSharp/Northwind/Product.cs ================================================ using System; using System.Collections.ObjectModel; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "Products")] public class Product { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int ProductID { get; set; } [Column] public string ProductName { get; set; } [Column] public int? SupplierID { get; set; } [Column] public int? CategoryID { get; set; } [Column] public string QuantityPerUnit { get; set; } [Column] public decimal? UnitPrice { get; set; } [Column] public short? UnitsInStock { get; set; } [Column] public short? UnitsOnOrder { get; set; } [Column] public short? ReorderLevel { get; set; } [Column] public bool Discontinued { get; set; } [Association(OtherKey = nameof(OrderDetail.ProductID))] public Collection OrderDetails { get; } = new(); [Association(ThisKey = nameof(CategoryID))] public Category Category { get; set; } [Association(ThisKey = nameof(SupplierID))] public Supplier Supplier { get; set; } } } ================================================ FILE: samples/CSharp/Northwind/Region.cs ================================================ using System; using System.Collections.ObjectModel; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "Region")] public class Region { [Column(IsPrimaryKey = true)] public int RegionID { get; set; } [Column] public string RegionDescription { get; set; } [Association(OtherKey = nameof(Territory.RegionID))] public Collection Territories { get; } = new(); } } ================================================ FILE: samples/CSharp/Northwind/Shipper.cs ================================================ using System; using System.Collections.ObjectModel; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "Shippers")] public class Shipper { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int ShipperID { get; set; } [Column] public string CompanyName { get; set; } [Column] public string Phone { get; set; } [Association(OtherKey = nameof(Order.ShipVia))] public Collection Orders { get; } = new(); } } ================================================ FILE: samples/CSharp/Northwind/Supplier.cs ================================================ using System; using System.Collections.ObjectModel; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "Suppliers")] public class Supplier { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int SupplierID { get; set; } [Column] public string CompanyName { get; set; } [Column] public string ContactName { get; set; } [Column] public string ContactTitle { get; set; } [Column] public string Address { get; set; } [Column] public string City { get; set; } [Column] public string Region { get; set; } [Column] public string PostalCode { get; set; } [Column] public string Country { get; set; } [Column] public string Phone { get; set; } [Column] public string Fax { get; set; } [Association(OtherKey = nameof(Product.SupplierID))] public Collection Products { get; } = new(); } } ================================================ FILE: samples/CSharp/Northwind/Territory.cs ================================================ using System; using System.Collections.ObjectModel; using DbExtensions; namespace Samples.CSharp.Northwind { [Table(Name = "Territories")] public class Territory { [Column(IsPrimaryKey = true)] public string TerritoryID { get; set; } [Column] public string TerritoryDescription { get; set; } [Column] public int RegionID { get; set; } [Association(OtherKey = nameof(EmployeeTerritory.TerritoryID))] public Collection EmployeeTerritories { get; } = new(); [Association(ThisKey = nameof(RegionID))] public Region Region { get; set; } } } ================================================ FILE: samples/CSharp/Samples.CSharp.csproj ================================================  net8.0 12 ================================================ FILE: samples/CSharp/SqlBuilder.cs ================================================ using System; using DbExtensions; namespace Samples.CSharp { public class SqlBuilderSamples { #pragma warning disable CA1822 public SqlBuilder DynamicSql_1() { return DynamicSql(2, 3); } public SqlBuilder DynamicSql_2() { return DynamicSql(null, 3); } public SqlBuilder DynamicSql_3() { return DynamicSql(2, null); } public SqlBuilder DynamicSql_4() { return DynamicSql(null, null); } SqlBuilder DynamicSql(int? categoryId, int? supplierId) { return SQL .SELECT("p.ProductID, p.ProductName") .FROM("Products p") .WHERE() ._If(categoryId.HasValue, $"p.CategoryID = {categoryId.Value}") ._If(supplierId.HasValue, $"p.SupplierID = {supplierId.Value}") .ORDER_BY("p.ProductName, p.ProductID DESC"); } public SqlBuilder Subquery() { return SQL .SELECT($"o.OrderID, o.CustomerID, ({SQL .SELECT("COUNT(od.Quantity)") .FROM("OrderDetails od") .WHERE("od.OrderID = o.OrderID")}) AS TotalItems") .FROM("Orders o"); } public SqlBuilder ExtendRawSql() { return ((SqlBuilder)$""" SELECT ProductID, ProductName FROM Products """) .WHERE($"CategoryID = {1}"); } public SqlBuilder ListArgument() { int[] range = { 1, 2, 3 }; return SQL .SELECT("p.ProductID, p.CategoryID") .FROM("Products p") .WHERE($"p.CategoryID = {1} AND p.ProductID IN ({range:list})") ._($"EXISTS ({SQL .SELECT("ProductID") .FROM("OrderDetails") .WHERE($"OrderID = {77}")})") .GROUP_BY("p.ProductID"); } public SqlBuilder Insert() { return SQL .INSERT_INTO("Products(ProductName, UnitPrice, CategoryID)") .VALUES("Chai", 15.56, 5); } public SqlBuilder Update() { return SQL .UPDATE("Products") .SET($"Discontinued = {true}") .WHERE($"ProductID = {1}"); } public SqlBuilder UpdateWithSubquery() { return SQL .UPDATE("Products p") .SET($"p.Discontinued = {true}") .WHERE($"p.ProductID = ({SQL .SELECT("p2.ProductID") .FROM("Products p2") .WHERE("p2.ProductID <> p.ProductID")})"); } public SqlBuilder Delete() { return SQL .DELETE_FROM("Products") .WHERE($"ProductID = {1}"); } /// /// SELECT Products.*, Categories.CategoryName /// FROM Categories INNER JOIN Products ON Categories.CategoryID = Products.CategoryID /// WHERE (((Products.Discontinued)=0)) /// /// Northwind.Alphabetical list of products public SqlBuilder AlphabeticalListOfProducts() { return SQL .SELECT("Products.*, Categories.CategoryName") .FROM("Categories") .LEFT_JOIN("Products ON Categories.CategoryID = Products.CategoryID") .WHERE($"Products.Discontinued = {0}"); } /// /// SELECT City, CompanyName, ContactName, 'Customers' AS Relationship /// FROM Customers /// UNION SELECT City, CompanyName, ContactName, 'Suppliers' /// FROM Suppliers /// /// Northwind.Customer and Suppliers by City public SqlBuilder CustomersAndSuppliersByCity() { return SQL .SELECT("City, CompanyName, ContactName, 'Customers' AS Relationship") .FROM("Customers") .UNION() .SELECT("City, CompanyName, ContactName, 'Suppliers'") .FROM("Suppliers"); } /// /// SELECT Products.ProductName, Products.UnitPrice /// FROM Products /// WHERE Products.UnitPrice > (SELECT AVG(UnitPrice) From Products) /// /// Northwind.Products Above Average Price public SqlBuilder ProductsAboveAveragePrice() { return SQL .SELECT("Products.ProductName, Products.UnitPrice") .FROM("Products") .WHERE($"Products.UnitPrice > ({SQL .SELECT("AVG(UnitPrice)") .FROM("Products")})"); } /// /// SELECT Categories.CategoryName, Products.ProductName, /// Sum(CONVERT(money,("Order Details".UnitPrice*Quantity*(1-Discount)/100))*100) AS ProductSales /// FROM (Categories INNER JOIN Products ON Categories.CategoryID = Products.CategoryID) /// INNER JOIN (Orders /// INNER JOIN "Order Details" ON Orders.OrderID = "Order Details".OrderID) /// ON Products.ProductID = "Order Details".ProductID /// WHERE (((Orders.ShippedDate) Between '19970101' And '19971231')) /// GROUP BY Categories.CategoryName, Products.ProductName /// /// Northwind.Product Sales for 1997 public SqlBuilder ProductSalesFor1997() { return SQL .SELECT("Categories.CategoryName, Products.ProductName, Sum(CONVERT(money,(\"Order Details\".UnitPrice*Quantity*(1-Discount)/100))*100) AS ProductSales") .FROM("(Categories").INNER_JOIN("Products ON Categories.CategoryID = Products.CategoryID)") .INNER_JOIN("(Orders").INNER_JOIN("\"Order Details\" ON Orders.OrderID = \"Order Details\".OrderID) ON Products.ProductID = \"Order Details\".ProductID") .WHERE($"(((Orders.ShippedDate) Between {new DateTime(1997, 1, 1)} And {new DateTime(1997, 12, 31)}))") .GROUP_BY("Categories.CategoryName, Products.ProductName"); } } } ================================================ FILE: samples/CSharp/SqlSet.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using DbExtensions; using Samples.CSharp.Northwind; namespace Samples.CSharp { public class SqlSetSamples { readonly SqlSet products; public SqlSetSamples(Database db) { this.products = db.From("Products"); } public bool AreThereAnyProducts() { return products.Any(); } public bool DoAllProductsHaveUnitPrice() { return products.All("NOT UnitPrice IS NULL"); } public bool DoSomeProductsAreOutOfStock() { return products.Any("UnitsInStock = 0"); } public int HowManyProductsAreOutOfStock() { return products.Count("UnitsInStock = 0"); } public Product FirstProduct() { return products.First(); } public Product SecondProduct() { return products.Skip(1).First(); } public Product FirstOutOfStockProduct() { return products.First("UnitsInStock = 0"); } public IEnumerable Top5ProductsWithLowestStock() { return products .Where("UnitsInStock > 0") .OrderBy("UnitsInStock") .Take(5) .Select("ProductName, UnitsInStock", r => new { Name = r.GetString(0), UnitsInStock = r.GetInt16(1) }) .AsEnumerable(); } public IEnumerable NamesOfOutOfStockProducts() { return products .Where("UnitsInStock = 0") .Select("ProductName", r => r.GetString(0)) .AsEnumerable(); } public Product GetSpecificProduct() { return products.SingleOrDefault("ProductID = 5"); } } } ================================================ FILE: src/DbExtensions/.editorconfig ================================================ [*.cs] # CA2007: Consider calling ConfigureAwait on the awaited task dotnet_diagnostic.CA2007.severity = warning ================================================ FILE: src/DbExtensions/Attributes.cs ================================================ // Copyright 2016-2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #region Based on code from .NET Framework #endregion using System; namespace DbExtensions; #nullable enable [AttributeUsage(AttributeTargets.Class)] sealed class DatabaseAttribute : Attribute { public string? Name { get; set; } } /// /// Designates a class as an entity class that is associated with a database table. /// [AttributeUsage(AttributeTargets.Class, Inherited = false)] public sealed class TableAttribute : Attribute { /// /// Gets or sets the name of the table or view. /// public string? Name { get; set; } } /// /// Associates a property with a column in a database table. /// [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public sealed class ColumnAttribute : Attribute, IDataAttribute { bool _canBeNull = true; bool _canBeNullSet = false; /// /// Gets or sets the name of a column. /// public string? Name { get; set; } /// /// Gets or sets a private storage field to hold the value from a column. /// string? IDataAttribute.Storage { get; set; } /// /// Gets or sets the type of the database column. /// internal string? DbType { get; set; } /// /// Gets or sets the type to convert this member to before sending to the database. /// public Type? ConvertTo { get; set; } internal string? Expression { get; set; } /// /// Gets or sets whether this class member represents a column that is part or all of the primary key of the table. /// public bool IsPrimaryKey { get; set; } /// /// Gets or sets whether a column contains values that the database auto-generates. /// public bool IsDbGenerated { get; set; } /// /// Gets or sets whether the column type of the member is a database timestamp or version number. /// public bool IsVersion { get; set; } internal UpdateCheck UpdateCheck { get; set; } = UpdateCheck.Always; /// /// Gets or sets the enumeration. /// public AutoSync AutoSync { get; set; } = AutoSync.Default; internal bool IsDiscriminator { get; set; } internal bool CanBeNull { get => _canBeNull; set { _canBeNullSet = true; _canBeNull = value; } } internal bool CanBeNullSet => _canBeNullSet; } internal enum UpdateCheck { Always, Never, WhenChanged } /// /// Used to specify for during INSERT and UPDATE operations when /// a data member should be read back after the operation completes. /// public enum AutoSync { /// /// Automatically selects the value. /// Default = 0, // Automatically choose /// /// Always returns the value. /// Always = 1, /// /// Never returns the value. /// Never = 2, /// /// Returns the value only after an INSERT operation. /// OnInsert = 3, /// /// Returns the value only after an UPDATE operation. /// OnUpdate = 4 } /// /// Designates a property to represent a database association, such as a foreign key relationship. /// [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public sealed class AssociationAttribute : Attribute, IDataAttribute { /// /// Gets or sets the name of a constraint. /// public string? Name { get; set; } /// /// Gets or sets a private storage field to hold the value for the association property. /// string? IDataAttribute.Storage { get; set; } /// /// Gets or sets members of this entity class to represent the key values on this side of the association. /// public string? ThisKey { get; set; } /// /// Gets or sets one or more members of the target entity class as key values on the other side of the association. /// public string? OtherKey { get; set; } /// /// Gets or sets the indication of a uniqueness constraint on the foreign key. /// /// When true, this property indicates a true 1:1 relationship. internal bool IsUnique { get; set; } /// /// Gets or sets the member as the foreign key in an association representing a database relationship. /// internal bool IsForeignKey { get; set; } internal string? DeleteRule { get; set; } internal bool DeleteOnNull { get; set; } } /// /// Class attribute used to describe an inheritance hierarchy to be mapped. /// For example, /// /// [Table(Name = "People")] /// [InheritanceMapping("P", typeof(Person), IsDefault=true)] /// [InheritanceMapping("C", typeof(Customer))] /// [InheritanceMapping("E", typeof(Employee))] /// class Person { ... } /// /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] sealed class InheritanceMappingAttribute : Attribute { /// /// Discriminator value in store column for this type. /// public object Code { get; } /// /// Type to instantiate when Key is matched. /// public Type Type { get; } /// /// If discriminator value in store column is unrecognized then instantiate this type. /// public bool IsDefault { get; set; } public InheritanceMappingAttribute(object code, Type type) { ArgumentNullException.ThrowIfNull(code); ArgumentNullException.ThrowIfNull(type); this.Code = code; this.Type = type; } } interface IDataAttribute { string? Name { get; set; } string? Storage { get; set; } } /// /// Designates a property as a complex property that groups columns of a table that share the same base name. /// [AttributeUsage(AttributeTargets.Property)] public sealed class ComplexPropertyAttribute : Attribute { /// /// The base name for the columns on the complex property. /// The default is the property name. /// public string? Name { get; set; } /// /// The separator to use between the base name and the complex property's columns. /// The default is null, which means the separator is taken from . /// To use no separator and override the default configuration, use an empty . /// public string? Separator { get; set; } /// /// Initializes a new instance of the class /// public ComplexPropertyAttribute() { } internal ComplexPropertyAttribute(ComplexPropertyAttribute other) { this.Name = other.Name; this.Separator = other.Separator; } } ================================================ FILE: src/DbExtensions/Database.cs ================================================ // Copyright 2009-2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.Common; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; namespace DbExtensions; #nullable enable #if DBEX_QE /// /// Provides simple data access using and . /// #else /// /// Provides simple data access using , and . /// #endif public partial class Database : IDisposable { readonly bool _disposeConn; /// /// Gets the connection to associate with new commands. /// public DbConnection Connection { get; } /// /// Gets or sets a transaction to associate with new commands. /// public DbTransaction? Transaction { get; set; } /// /// Provides access to configuration options for this instance. /// public DatabaseConfiguration Configuration { get; private set; } /// /// Initializes a new instance of the class /// using the provided connection string and provider's invariant name. /// /// The connection string. /// The provider's invariant name. #pragma warning disable CS8618 public Database(string connectionString, string providerInvariantName) { ArgumentNullException.ThrowIfNull(connectionString); ArgumentNullException.ThrowIfNull(providerInvariantName); var factory = DbProviderFactories.GetFactory(providerInvariantName); var connection = factory.CreateConnection() ?? throw new ArgumentException("The provider factory CreateConnection() returned null.", nameof(providerInvariantName)); connection.ConnectionString = connectionString; this.Connection = connection; _disposeConn = true; Initialize(providerInvariantName); } /// /// Initializes a new instance of the class /// using the provided connection. /// /// The connection. public Database(DbConnection connection) { ArgumentNullException.ThrowIfNull(connection); this.Connection = connection; Initialize(null); } internal // Used by tests Database(DbConnection connection, string providerInvariantName) { ArgumentNullException.ThrowIfNull(connection); ArgumentNullException.ThrowIfNull(providerInvariantName); this.Connection = connection; Initialize(providerInvariantName); } #pragma warning restore CS8618 void Initialize(string? providerInvariantName) { providerInvariantName ??= this.Connection.GetType().Namespace ?? throw new InvalidOperationException("Couldn't determine provider invariant name."); this.Configuration = new DatabaseConfiguration( providerInvariantName, () => CreateCommandBuilder(providerInvariantName)); Initialize2(providerInvariantName); } partial void Initialize2(string providerInvariantName); DbCommandBuilder? CreateCommandBuilder(string providerInvariantName) { var factory = DbProviderFactories.GetFactory(this.Connection) ?? DbProviderFactories.GetFactory(providerInvariantName); return factory.CreateCommandBuilder(); } /// /// Opens (if it's not open) and returns an object /// you can use to close it (if it wasn't open). /// /// An object to close the connection. /// /// Use this method with the using statement in C# or Visual Basic to ensure that a block of code /// is always executed with an open connection. /// /// /// /// using (db.EnsureConnectionOpen()) { /// // Execute commands. /// } /// /// public IDisposable EnsureConnectionOpen() { var conn = this.Connection; var wasClosed = (conn.State == ConnectionState.Closed); if (wasClosed) { conn.Open(); } return new WrappedConnection((wasClosed) ? conn : null); } /// /// Opens (if it's not open) and returns an object /// you can use to close it (if it wasn't open). /// /// The to monitor for cancellation requests. The default is . /// An object to close the connection. /// /// Use this method with the using statement in C# or Visual Basic to ensure that a block of code /// is always executed with an open connection. /// /// /// /// await using (await db.EnsureConnectionOpenAsync()) { /// // Execute commands. /// } /// /// public async ValueTask EnsureConnectionOpenAsync(CancellationToken cancellationToken = default) { var conn = this.Connection; var wasClosed = (conn.State == ConnectionState.Closed); if (wasClosed) { await conn.OpenAsync(cancellationToken) .ConfigureAwait(false); } return new WrappedConnection((wasClosed) ? conn : null); } /// /// Returns a virtual transaction that you can use to ensure a code block is always executed in /// a transaction, new or existing. /// /// /// A virtual transaction you can use to ensure a code block is always executed in /// a transaction, new or existing. /// /// /// This method returns a virtual transaction that wraps an existing or new transaction. /// By calling on the returned object, this object /// will then call on the wrapped transaction if the /// transaction was just created, or do nothing if it was previously created. /// /// /// /// Calls to this method can be nested, like in the following example: /// /// /// void DoSomething() { /// /// using (var tx = this.db.EnsureInTransaction()) { /// /// // Execute commands /// /// DoSomethingElse(); /// /// tx.Commit(); /// } /// } /// /// void DoSomethingElse() { /// /// using (var tx = this.db.EnsureInTransaction()) { /// /// // Execute commands /// /// tx.Commit(); /// } /// } /// /// public DbTransaction EnsureInTransaction() => EnsureInTransaction(IsolationLevel.Unspecified); /// /// /// Specifies the isolation level for the transaction. This parameter is ignored when using /// an existing transaction. /// public virtual DbTransaction EnsureInTransaction(IsolationLevel isolationLevel) { var connHolder = (WrappedConnection)EnsureConnectionOpen(); var newTx = default(DbTransaction); try { if (this.Transaction is null) { this.Transaction = (newTx = this.Connection.BeginTransaction(isolationLevel)); this.Configuration.Log?.WriteLine("-- TRANSACTION STARTED"); } } catch { connHolder.Dispose(); throw; } if (newTx != null) { return new WrappedTransaction(this, newTx, connHolder); } return new NoOpTransaction(this.Connection, isolationLevel, connHolder); } /// /// /// /// /// Calls to this method can be nested, like in the following example: /// /// /// async Task DoSomething() { /// /// await using (var tx = await this.db.EnsureInTransactionAsync()) { /// /// // Execute commands /// /// await DoSomethingElse(); /// /// await tx.CommitAsync(); /// } /// } /// /// async Task DoSomethingElse() { /// /// await using (var tx = await this.db.EnsureInTransactionAsync()) { /// /// // Execute commands /// /// await tx.CommitAsync(); /// } /// } /// /// public ValueTask EnsureInTransactionAsync(CancellationToken cancellationToken = default) => EnsureInTransactionAsync(IsolationLevel.Unspecified, cancellationToken); /// /// public virtual async ValueTask EnsureInTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken = default) { var connHolder = (WrappedConnection)EnsureConnectionOpen(); var newTx = default(DbTransaction); try { if (this.Transaction is null) { this.Transaction = (newTx = await this.Connection.BeginTransactionAsync(isolationLevel, cancellationToken) .ConfigureAwait(false)); this.Configuration.Log?.WriteLine("-- TRANSACTION STARTED"); } } catch { await connHolder.DisposeAsync() .ConfigureAwait(false); throw; } if (newTx != null) { return new WrappedTransaction(this, newTx, connHolder); } return new NoOpTransaction(this.Connection, isolationLevel, connHolder); } /// /// Executes the command. Optionally uses a transaction and validates /// affected records value before committing. /// /// The non-query command to execute. /// The number of records the command should affect. This value is ignored if less or equal to -1. /// true if the number of affected records should exactly match ; false if a lower number is acceptable. /// The number of affected records. /// The number of affected records is not equal to . public int Execute(SqlBuilder nonQuery, int affect = -1, bool exact = false) { ArgumentNullException.ThrowIfNull(nonQuery); var command = CreateCommand(nonQuery); var validateAffected = affect > -1; using var conn = EnsureConnectionOpen(); using var tx = (validateAffected) ? EnsureInTransaction() : null; command.Transaction = this.Transaction; int affectedRecords; try { affectedRecords = command.ExecuteNonQuery(); } catch { Trace(command, error: true); throw; } OnExecuted(command, affect, exact, validateAffected, affectedRecords); tx?.Commit(); return affectedRecords; } /// /// public async ValueTask ExecuteAsync(SqlBuilder nonQuery, int affect = -1, bool exact = false, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(nonQuery); var command = CreateCommand(nonQuery); var validateAffected = affect > -1; await using var conn = (await EnsureConnectionOpenAsync(cancellationToken) .ConfigureAwait(false)) .ConfigureAwait(false); var tx = (validateAffected) ? await EnsureInTransactionAsync(cancellationToken).ConfigureAwait(false) : new NoOpTransaction(this.Connection, IsolationLevel.Unspecified, new WrappedConnection(null)); await using var txDisp = tx.ConfigureAwait(false); command.Transaction = this.Transaction; int affectedRecords; try { affectedRecords = await command.ExecuteNonQueryAsync(cancellationToken) .ConfigureAwait(false); } catch { Trace(command, error: true); throw; } OnExecuted(command, affect, exact, validateAffected, affectedRecords); await tx.CommitAsync(cancellationToken) .ConfigureAwait(false); return affectedRecords; } void OnExecuted(DbCommand command, int affect, bool exact, bool validateAffected, int affectedRecords) { Trace(command, affectedRecords); if (validateAffected && affectedRecords != affect) { if (exact) { throw new ChangeConflictException(String.Create( CultureInfo.InvariantCulture, $"The number of affected records should be {affect}, the actual number is {affectedRecords}.")); } else if (affectedRecords > affect) { throw new ChangeConflictException(String.Create( CultureInfo.InvariantCulture, $"The number of affected records should be {affect} or lower, the actual number is {affectedRecords}.")); } } } /// /// Maps the results of the to objects, /// using the provided delegate. /// /// The type of objects to map the results to. /// The query. /// The delegate for creating objects from an object. /// The results of the query as objects. public IEnumerable Map(SqlBuilder query, Func mapper) { ArgumentNullException.ThrowIfNull(query); ArgumentNullException.ThrowIfNull(mapper); return new MappingEnumerable(CreateCommand(query), mapper, this.Configuration.Log); } /// public IAsyncEnumerable AsyncMap(SqlBuilder query, Func mapper) { ArgumentNullException.ThrowIfNull(query); ArgumentNullException.ThrowIfNull(mapper); return new AsyncMappingEnumerable(CreateCommand(query), mapper, this.Configuration.Log); } /// /// Gets the identity value of the last inserted record. /// /// The identity value of the last inserted record. /// /// It is very important to keep the connection open between the last /// command and this one, or else you might get the wrong value. /// public virtual object? LastInsertId() { var sql = this.Configuration.LastInsertIdCommand; if (String.IsNullOrEmpty(sql)) { throw new InvalidOperationException("Configuration.LastInsertIdCommand cannot be null or empty."); } var command = CreateCommand(new SqlBuilder(sql.Length, 0).Append(sql)); var value = command.ExecuteScalar(); Trace(command); return value; } /// /// public virtual async ValueTask LastInsertIdAsync(CancellationToken cancellationToken = default) { var sql = this.Configuration.LastInsertIdCommand; if (String.IsNullOrEmpty(sql)) { throw new InvalidOperationException("Configuration.LastInsertIdCommand cannot be null or empty."); } var command = CreateCommand(new SqlBuilder(sql.Length, 0).Append(sql)); var value = await command.ExecuteScalarAsync(cancellationToken) .ConfigureAwait(false); Trace(command); return value; } /// /// Creates and returns a object from the specified . /// /// The that provides the command's text and parameters. /// /// A new object with its property /// initialized with the 's string representation, and its /// property is initialized with the values from the property of the parameter. /// public virtual DbCommand CreateCommand(SqlBuilder sqlBuilder) { ArgumentNullException.ThrowIfNull(sqlBuilder); var command = this.Connection.CreateCommand(); var format = sqlBuilder.ToString(); var parameters = sqlBuilder.ParameterValues; if (this.Transaction is { } tx) { command.Transaction = tx; } if (this.Configuration.CommandTimeout is { } timeout and > -1) { command.CommandTimeout = timeout; } if (parameters is null or { Count: 0 }) { command.CommandText = format; return command; } var paramPlaceholders = new object[parameters.Count]; for (int i = 0; i < paramPlaceholders.Length; i++) { var paramValue = parameters[i]; var dbParam = paramValue as DbParameter; if (dbParam is null) { dbParam = command.CreateParameter(); dbParam.Value = paramValue ?? DBNull.Value; } dbParam.ParameterName = this.Configuration.ParameterNameBuilder .Invoke($"p{i}"); command.Parameters.Add(dbParam); paramPlaceholders[i] = this.Configuration.ParameterPlaceholderBuilder .Invoke(dbParam.ParameterName); } command.CommandText = String.Format(CultureInfo.InvariantCulture, format, paramPlaceholders); return command; } /// /// Given an unquoted identifier in the correct catalog case, returns the correct quoted form of that identifier. /// /// The original identifier. /// The quoted version of the identifier. If the indentifier is already quoted it's returned unchanged. public string QuoteIdentifier(string identifier) { QuoteIdentifierImpl(identifier, out var quotePrefix, out var quoteSuffix); return String.Concat(quotePrefix, identifier, quoteSuffix); } internal void QuoteIdentifier(StringBuilder sb, string identifier) { QuoteIdentifierImpl(identifier, out var quotePrefix, out var quoteSuffix); sb.Append(quotePrefix); sb.Append(identifier); sb.Append(quoteSuffix); } void QuoteIdentifierImpl(string identifier, out string quotePrefix, out string quoteSuffix) { ArgumentNullException.ThrowIfNull(identifier); quotePrefix = this.Configuration.QuotePrefix; quoteSuffix = this.Configuration.QuoteSuffix; if (quotePrefix.Length == 0 && quoteSuffix.Length == 0) { return; } if (identifier.StartsWith(quotePrefix, StringComparison.Ordinal) && identifier.EndsWith(quoteSuffix, StringComparison.Ordinal)) { quotePrefix = String.Empty; quoteSuffix = String.Empty; } } internal void Trace(DbCommand command, int? affectedRecords = null, bool error = false) => Trace(command, this.Configuration.Log, affectedRecords, error); internal static void Trace(DbCommand command, TextWriter? log, int? affectedRecords = null, bool error = false) { if (log is not null) { log.WriteLine(); if (error) { log.WriteLine("-- ERROR: The following command produced an error"); } log.WriteLine(command.CommandText); for (int i = 0; i < command.Parameters.Count; i++) { var param = command.Parameters[i]; if (param is not null) { log.WriteLine(String.Create(log.FormatProvider, $"-- {param.ParameterName}: {param.Direction} {param.DbType} (Size = {param.Size}) [{param.Value}]")); } } if (affectedRecords is not null) { log.WriteLine(String.Create(log.FormatProvider, $"-- [{affectedRecords.Value}] records affected.")); } } } /// /// Releases all resources used by the current instance of the class. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Releases the resources used by this instance. /// /// /// true if this method is being called due to a call to ; otherwise, false. /// protected virtual void Dispose(bool disposing) { if (disposing) { if (_disposeConn) { this.Connection?.Dispose(); } } } // Object Members /// [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object? obj) => base.Equals(obj); /// [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() => base.GetHashCode(); /// [EditorBrowsable(EditorBrowsableState.Never)] public new Type GetType() => base.GetType(); /// [EditorBrowsable(EditorBrowsableState.Never)] public override string? ToString() => base.ToString(); sealed class WrappedConnection(DbConnection? previouslyClosedConn) : IDisposable, IAsyncDisposable { public void Dispose() { if (previouslyClosedConn is { State: not ConnectionState.Closed } conn) { conn.Close(); } } public async ValueTask DisposeAsync() { if (previouslyClosedConn is { State: not ConnectionState.Closed } conn) { await conn.CloseAsync() .ConfigureAwait(false); } } } sealed class WrappedTransaction : DbTransaction { readonly Database _db; readonly DbTransaction _tx; readonly WrappedConnection _connHolder; protected override DbConnection? DbConnection => _tx.Connection; public override IsolationLevel IsolationLevel => _tx.IsolationLevel; public WrappedTransaction(Database db, DbTransaction tx, WrappedConnection connHolder) { _db = db; _tx = tx; _connHolder = connHolder; } public override void Commit() { try { _tx.Commit(); _db.Configuration.Log?.WriteLine("-- TRANSACTION COMMITED"); } finally { RemoveTxFromDatabase(); } } public override async Task CommitAsync(CancellationToken cancellationToken = default) { try { await _tx.CommitAsync(cancellationToken) .ConfigureAwait(false); _db.Configuration.Log?.WriteLine("-- TRANSACTION COMMITED"); } finally { RemoveTxFromDatabase(); } } public override void Rollback() { try { _tx.Rollback(); _db.Configuration.Log?.WriteLine("-- TRANSACTION ROLLED BACK"); } finally { RemoveTxFromDatabase(); } } public override async Task RollbackAsync(CancellationToken cancellationToken = default) { try { await _tx.RollbackAsync(cancellationToken) .ConfigureAwait(false); _db.Configuration.Log?.WriteLine("-- TRANSACTION ROLLED BACK"); } finally { RemoveTxFromDatabase(); } } protected override void Dispose(bool disposing) { if (disposing) { try { try { _tx.Dispose(); } finally { RemoveTxFromDatabase(); } } finally { _connHolder.Dispose(); } } } public override async ValueTask DisposeAsync() { try { try { await _tx.DisposeAsync() .ConfigureAwait(false); } finally { RemoveTxFromDatabase(); } } finally { await _connHolder.DisposeAsync() .ConfigureAwait(false); } } void RemoveTxFromDatabase() { if (Object.ReferenceEquals(_tx, _db.Transaction)) { _db.Transaction = null; } } } sealed class NoOpTransaction(DbConnection conn, IsolationLevel isolationLevel, WrappedConnection connHolder) : DbTransaction { protected override DbConnection? DbConnection => conn; public override IsolationLevel IsolationLevel => isolationLevel; public override void Commit() { } public override void Rollback() => throw new NotImplementedException(); protected override void Dispose(bool disposing) { if (disposing) { connHolder.Dispose(); } } public override async ValueTask DisposeAsync() { await connHolder.DisposeAsync() .ConfigureAwait(false); } } } /// /// Holds configuration options that customize the behavior of . /// This class cannot be instantiated, to get an instance use the property. /// public sealed partial class DatabaseConfiguration { static readonly Func _getParameterNameI = (Func) Delegate.CreateDelegate(typeof(Func), typeof(DbCommandBuilder) .GetMethod("GetParameterName", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, [typeof(int)], null)!); static readonly Func _getParameterNameS = (Func) Delegate.CreateDelegate(typeof(Func), typeof(DbCommandBuilder) .GetMethod("GetParameterName", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, [typeof(string)], null)!); static readonly Func _getParameterPlaceholder = (Func) Delegate.CreateDelegate(typeof(Func), typeof(DbCommandBuilder) .GetMethod("GetParameterPlaceholder", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, [typeof(int)], null)!); string? _quotePrefix; string? _quoteSuffix; Func? _parameterNameBuilder; Func? _parameterPlaceholderBuilder; string? _lastInsertIdCommand; /// /// Gets or sets the beginning character or characters to use when specifying database objects (for example, tables or columns) /// whose names contain characters such as spaces or reserved tokens. /// [AllowNull] public string QuotePrefix { get => _quotePrefix ?? "["; set => _quotePrefix = value; } /// /// Gets or sets the ending character or characters to use when specifying database objects (for example, tables or columns) /// whose names contain characters such as spaces or reserved tokens. /// [AllowNull] public string QuoteSuffix { get => _quoteSuffix ?? "]"; set => _quoteSuffix = value; } /// /// Specifies a function that prepares a parameter name to be used on . /// [AllowNull] public Func ParameterNameBuilder { get => _parameterNameBuilder ?? DefaultParameterNameBuilder; set => _parameterNameBuilder = value; } /// /// Specifies a function that builds a parameter placeholder to be used in SQL statements. /// [AllowNull] public Func ParameterPlaceholderBuilder { get => _parameterPlaceholderBuilder ?? DefaultParameterPlaceholderBuilder; set => _parameterPlaceholderBuilder = value; } /// /// Gets or sets the SQL command that returns the last identity value generated on the database. /// [AllowNull] public string LastInsertIdCommand { get => _lastInsertIdCommand ?? "SELECT @@IDENTITY"; set => _lastInsertIdCommand = value; } /// /// Specifies the destination to write the SQL query or command. /// public TextWriter? Log { get; set; } /// /// Specifies a timeout to assign to commands. This setting is ignored if less or equal to -1. The default is -1. /// public int CommandTimeout { get; set; } = -1; internal SqlDialect SqlDialect { get; set; } static string DefaultParameterNameBuilder(string name) => "@" + name; static string DefaultParameterPlaceholderBuilder(string name) => name; #pragma warning disable CS8618 internal DatabaseConfiguration(string providerInvariantName, Func? cbFn = null) { #pragma warning restore CS8618 switch (providerInvariantName) { case "Microsoft.Data.SqlClient": this.LastInsertIdCommand = "SELECT SCOPE_IDENTITY()"; this.SqlDialect = SqlDialect.TSql; break; case "MySql.Data.MySqlClient": this.QuotePrefix = "`"; this.QuoteSuffix = this.QuotePrefix; break; case "System.Data.Odbc": case "System.Data.OleDb": this.ParameterNameBuilder = (name) => name; this.ParameterPlaceholderBuilder = (paramName) => "?"; break; case "System.Data.SQLite": this.LastInsertIdCommand = "SELECT LAST_INSERT_ROWID()"; break; default: if (cbFn?.Invoke() is { } cb) { Initialize(cb); } break; } } void Initialize(DbCommandBuilder cb) { var qp = cb.QuotePrefix; var qs = cb.QuoteSuffix; if (!String.IsNullOrEmpty(qp) || !String.IsNullOrEmpty(qs)) { this.QuotePrefix = qp ?? String.Empty; this.QuoteSuffix = qs ?? String.Empty; } this.ParameterNameBuilder = (name) => _getParameterNameS.Invoke(cb, name); var pName = _getParameterNameI.Invoke(cb, 1); var pPlace = _getParameterPlaceholder.Invoke(cb, 1); if (!(Object.ReferenceEquals(pName, pPlace) || pName == pPlace)) { this.ParameterPlaceholderBuilder = (paramName) => pPlace.Replace(pName, paramName); } } } enum SqlDialect { Default = 0, TSql } /// /// An exception that is thrown when a concurrency violation is encountered while saving to the database. A concurrency violation /// occurs when an unexpected number of rows are affected during save. This is usually because the data in the database has /// been modified since it was loaded into memory. /// public sealed class ChangeConflictException : Exception { /// /// Initializes a new instance of the class /// with a specified error message. /// /// The message that describes the error. public ChangeConflictException(string message) : base(message) { } } sealed class MappingEnumerable : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { readonly DbCommand _command; readonly Func _mapper; readonly TextWriter? _logger; readonly bool _prevStateWasClosed; bool _used; DbDataReader? _reader; TResult _current; public TResult Current => _current; object IEnumerator.Current => Current!; #pragma warning disable CS8618 public MappingEnumerable(DbCommand command, Func mapper, TextWriter? logger) { #pragma warning restore CS8618 var conn = command.Connection ?? throw new ArgumentException("command.Connection cannot be null.", nameof(command)); _prevStateWasClosed = (conn.State == ConnectionState.Closed); _command = command; _mapper = mapper; _logger = logger; } public IEnumerator GetEnumerator() { if (!_used) { _used = true; return this; } throw new InvalidOperationException("Cannot enumerate more than once."); } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); public bool MoveNext() { if (_reader is null) { PossiblyOpenConnection(); try { _reader = _command.ExecuteReader(); Database.Trace(_command, _logger, _reader.RecordsAffected); } catch { try { Database.Trace(_command, _logger, error: true); } finally { PossiblyCloseConnection(); } throw; } } if (_reader.IsClosed) { // see MappingContext.LoadMany() return false; } try { if (_reader.Read()) { _current = _mapper.Invoke(_reader); return true; } } catch { PossiblyCloseConnection(); throw; } PossiblyCloseConnection(); return false; } public void Reset() => throw new NotSupportedException(); public void Dispose() { _reader?.Dispose(); PossiblyCloseConnection(); } void PossiblyOpenConnection() { if (_prevStateWasClosed) { _command.Connection?.Open(); } } void PossiblyCloseConnection() { if (_prevStateWasClosed && _command.Connection is { State: not ConnectionState.Closed } conn) { conn.Close(); } } } sealed class AsyncMappingEnumerable : IAsyncEnumerable, IAsyncEnumerator { readonly DbCommand _command; readonly Func _mapper; readonly TextWriter? _logger; readonly bool _prevStateWasClosed; bool _used; CancellationToken _cancellationToken; DbDataReader? _reader; TResult _current; public TResult Current => _current; #pragma warning disable CS8618 public AsyncMappingEnumerable(DbCommand command, Func mapper, TextWriter? logger) { #pragma warning restore CS8618 var conn = command.Connection ?? throw new ArgumentException("command.Connection cannot be null.", nameof(command)); _prevStateWasClosed = (conn.State == ConnectionState.Closed); _command = command; _mapper = mapper; _logger = logger; } public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) { if (!_used) { _cancellationToken = cancellationToken; _used = true; return this; } throw new InvalidOperationException("Cannot enumerate more than once."); } public async ValueTask MoveNextAsync() { if (_reader is null) { await PossiblyOpenConnection() .ConfigureAwait(false); try { _reader = await _command.ExecuteReaderAsync(_cancellationToken) .ConfigureAwait(false); Database.Trace(_command, _logger, _reader.RecordsAffected); } catch { try { Database.Trace(_command, _logger, error: true); } finally { await PossiblyCloseConnection() .ConfigureAwait(false); } throw; } } if (_reader.IsClosed) { // see MappingContext.LoadMany() return false; } try { if (await _reader.ReadAsync(_cancellationToken).ConfigureAwait(false)) { _current = _mapper.Invoke(_reader); return true; } } catch { await PossiblyCloseConnection() .ConfigureAwait(false); throw; } await PossiblyCloseConnection() .ConfigureAwait(false); return false; } async ValueTask PossiblyOpenConnection() { if (_prevStateWasClosed && _command.Connection is { } conn) { await conn.OpenAsync(_cancellationToken) .ConfigureAwait(false); } } async ValueTask PossiblyCloseConnection() { if (_prevStateWasClosed && _command.Connection is { State: not ConnectionState.Closed } conn) { await conn.CloseAsync() .ConfigureAwait(false); } } public async ValueTask DisposeAsync() { if (_reader is { } r) { await r.DisposeAsync() .ConfigureAwait(false); } await PossiblyCloseConnection() .ConfigureAwait(false); } } ================================================ FILE: src/DbExtensions/DbExtensions.csproj ================================================  net8.0 12 true 1573 DbExtensions is a data-access framework with a strong focus on query composition, granularity and code aesthetics. It supports both POCO and dynamic (untyped) mapping. ado.net orm micro-orm icon.png true true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb $(TargetsForTfmSpecificBuildOutput);IncludeXmlDoc ================================================ FILE: src/DbExtensions/DynamicMapper.cs ================================================ // Copyright 2013-2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections.Generic; using System.Data.Common; using System.Dynamic; using System.Linq; using System.Reflection; namespace DbExtensions; #nullable enable partial class Database { /// /// Maps the results of the to dynamic objects. /// The query is deferred-executed. /// /// The query. /// The results of the query as dynamic objects. public IEnumerable Map(SqlBuilder query) { ArgumentNullException.ThrowIfNull(query); var mapper = CreateDynamicMapper(); return Map(query, r => (dynamic)mapper.DynamicMap(r)); } /// public IAsyncEnumerable AsyncMap(SqlBuilder query) { ArgumentNullException.ThrowIfNull(query); var mapper = CreateDynamicMapper(); return AsyncMap(query, r => (dynamic)mapper.DynamicMap(r)); } internal DynamicMapper CreateDynamicMapper() { return new DynamicMapper { Log = this.Configuration.Log }; } } partial class SqlSet { partial void DynamicMap(bool singleResult, SqlBuilder query, ref IEnumerable? results) { var mapper = CreateDynamicMapper(singleResult); results = _db.Map(query, mapper.DynamicMap); } partial void DynamicAsyncMap(bool singleResult, SqlBuilder query, ref IAsyncEnumerable? results) { var mapper = CreateDynamicMapper(singleResult); results = _db.AsyncMap(query, mapper.DynamicMap); } DynamicMapper CreateDynamicMapper(bool singleResult) { var mapper = _db.CreateDynamicMapper(); mapper.SingleResult = singleResult; return mapper; } } sealed class DynamicMapper : Mapper { protected override bool CanUseConstructorMapping => false; protected override Node CreateRootNode() => new DynamicNode(); protected override Node CreateSimpleProperty(Node container, string propertyName, int columnOrdinal) => new DynamicNode(propertyName, columnOrdinal); protected override Node CreateComplexProperty(Node container, string propertyName) => new DynamicNode(propertyName, isComplex: true); protected override Node CreateParameterNode(ParameterInfo paramInfo) => throw new NotImplementedException(); protected override Node CreateParameterNode(int columnOrdinal, ParameterInfo paramInfo) => throw new NotImplementedException(); public object DynamicMap(DbDataReader record) { var node = (DynamicNode)GetRootNode(record); var context = this.MappingContext; var instance = node.Create(record, context); node.Load(instance, record, context); return instance; } } sealed class DynamicNode : Node { static readonly string _typeName = typeof(ExpandoObject).FullName!; public override bool IsComplex { get; } public override string? PropertyName { get; } public override int ColumnOrdinal { get; } public override string TypeName => _typeName; internal DynamicNode() { this.IsComplex = true; } internal DynamicNode(string propertyName, int columnOrdinal = default, bool isComplex = default) { ArgumentNullException.ThrowIfNull(propertyName); if (propertyName.Length == 0) { throw new ArgumentException("Cannot map column using an empty property name.", nameof(propertyName)); } if (UInt32.TryParse(propertyName, out _)) { throw new ArgumentException("Cannot use constructor mapping, by using numeric column names, unless you specify the type of the object you want to map to.", nameof(propertyName)); } this.PropertyName = propertyName; this.ColumnOrdinal = columnOrdinal; this.IsComplex = isComplex; } public object? Map(DbDataReader record, MappingContext context) { if (this.IsComplex) { return MapComplex(record, context); } return MapSimple(record, context); } object? MapComplex(DbDataReader record, MappingContext context) { if (AllColumnsNull(record)) { return null; } var value = Create(record, context); Load(value, record, context); return value; } bool AllColumnsNull(DbDataReader record) { if (this.IsComplex) { return (!this.HasConstructorParameters || this.ConstructorParameters .OrderBy(n => n.Value.IsComplex) .All(n => ((DynamicNode)n.Value).AllColumnsNull(record))) && this.Properties .OrderBy(n => n.IsComplex) .All(n => ((DynamicNode)n).AllColumnsNull(record)); } return record.IsDBNull(this.ColumnOrdinal); } object? MapSimple(DbDataReader record, MappingContext context) { var isNull = record.IsDBNull(this.ColumnOrdinal); var value = (isNull) ? null : record.GetValue(this.ColumnOrdinal); return value; } public object Create(DbDataReader record, MappingContext context) => new ExpandoObject(); public void Load(object instance, DbDataReader record, MappingContext context) { for (int i = 0; i < this.Properties.Count; i++) { var childNode = (DynamicNode)this.Properties[i]; if (!childNode.IsComplex || childNode.HasConstructorParameters) { childNode.Read(instance, record, context); continue; } var currentValue = childNode.Get(instance); if (currentValue is not null) { childNode.Load(currentValue, record, context); } else { childNode.Read(instance, record, context); } } } void Read(object instance, DbDataReader record, MappingContext context) { var value = Map(record, context); Set(instance, value, context); } object? Get(object instance) { var dictionary = (IDictionary)instance; if (dictionary.TryGetValue(this.PropertyName!, out var value)) { return value; } return null; } void Set(object instance, object? value, MappingContext context) { ((IDictionary)instance)[this.PropertyName!] = value; } public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) => throw new InvalidOperationException("Cannot use constructor mapping, by using numeric column names, unless you specify the type of the object you want to map to."); } ================================================ FILE: src/DbExtensions/Extensions.cs ================================================ // Copyright 2009-2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Data.Common; namespace DbExtensions; #nullable enable /// /// Provides extension methods for common ADO.NET objects. /// public static class Extensions { /// /// Gets the value of the specified column as a . /// /// public static Boolean GetBoolean(this DbDataReader reader, string name) => reader.GetBoolean(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a . /// /// public static Byte GetByte(this DbDataReader reader, string name) => reader.GetByte(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a . /// /// public static Char GetChar(this DbDataReader reader, string name) => reader.GetChar(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a . /// /// public static DateTime GetDateTime(this DbDataReader reader, string name) => reader.GetDateTime(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a . /// /// public static Decimal GetDecimal(this DbDataReader reader, string name) => reader.GetDecimal(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a . /// /// public static Double GetDouble(this DbDataReader reader, string name) => reader.GetDouble(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a . /// /// public static Single GetFloat(this DbDataReader reader, string name) => reader.GetFloat(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as an . /// /// public static Int16 GetInt16(this DbDataReader reader, string name) => reader.GetInt16(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as an . /// /// public static Int32 GetInt32(this DbDataReader reader, string name) => reader.GetInt32(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as an . /// /// public static Int64 GetInt64(this DbDataReader reader, string name) => reader.GetInt64(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a . /// /// public static String GetString(this DbDataReader reader, string name) => reader.GetString(reader.GetOrdinal(name)); /// /// Gets the value of the specified column. /// /// The data reader. /// The name of the column to find. /// The value of the column. public static Object GetValue(this DbDataReader reader, string name) => reader.GetValue(reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Boolean? GetNullableBoolean(this DbDataReader reader, string name) => GetNullableBoolean(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Boolean? GetNullableBoolean(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(Boolean?) : reader.GetBoolean(i); /// /// Gets the value of the specified column as a of . /// /// public static Byte? GetNullableByte(this DbDataReader reader, string name) => GetNullableByte(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Byte? GetNullableByte(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(Byte?) : reader.GetByte(i); /// /// Gets the value of the specified column as a of . /// /// public static Char? GetNullableChar(this DbDataReader reader, string name) => GetNullableChar(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Char? GetNullableChar(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(Char?) : reader.GetChar(i); /// /// Gets the value of the specified column as a of . /// /// public static DateTime? GetNullableDateTime(this DbDataReader reader, string name) => GetNullableDateTime(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static DateTime? GetNullableDateTime(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(DateTime?) : reader.GetDateTime(i); /// /// Gets the value of the specified column as a of . /// /// public static Decimal? GetNullableDecimal(this DbDataReader reader, string name) => GetNullableDecimal(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Decimal? GetNullableDecimal(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(Decimal?) : reader.GetDecimal(i); /// /// Gets the value of the specified column as a of . /// /// public static Double? GetNullableDouble(this DbDataReader reader, string name) => GetNullableDouble(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Double? GetNullableDouble(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(Double?) : reader.GetDouble(i); /// /// Gets the value of the specified column as a of . /// /// public static Single? GetNullableFloat(this DbDataReader reader, string name) => GetNullableFloat(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Single? GetNullableFloat(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(Single?) : reader.GetFloat(i); /// /// Gets the value of the specified column as a of . /// /// public static Guid? GetNullableGuid(this DbDataReader reader, string name) => GetNullableGuid(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Guid? GetNullableGuid(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(Guid?) : reader.GetGuid(i); /// /// Gets the value of the specified column as a of . /// /// public static Int16? GetNullableInt16(this DbDataReader reader, string name) => GetNullableInt16(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Int16? GetNullableInt16(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(Int16?) : reader.GetInt16(i); /// /// Gets the value of the specified column as a of . /// /// public static Int32? GetNullableInt32(this DbDataReader reader, string name) => GetNullableInt32(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Int32? GetNullableInt32(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(Int32?) : reader.GetInt32(i); /// /// Gets the value of the specified column as a of . /// /// public static Int64? GetNullableInt64(this DbDataReader reader, string name) => GetNullableInt64(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a of . /// /// public static Int64? GetNullableInt64(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(Int64?) : reader.GetInt64(i); /// /// Gets the value of the specified column as a , or null (Nothing in Visual Basic). /// /// public static String? GetStringOrNull(this DbDataReader reader, string name) => GetStringOrNull(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as a , or null (Nothing in Visual Basic). /// /// public static String? GetStringOrNull(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? default(String) : reader.GetString(i); /// /// Gets the value of the specified column as an , or null (Nothing in Visual Basic). /// /// public static Object? GetValueOrNull(this DbDataReader reader, string name) => GetValueOrNull(reader, reader.GetOrdinal(name)); /// /// Gets the value of the specified column as an , or null (Nothing in Visual Basic). /// /// The data reader. /// The zero-based column ordinal. /// The value of the column. public static Object? GetValueOrNull(this DbDataReader reader, int i) => (reader.IsDBNull(i)) ? null : reader.GetValue(i); } ================================================ FILE: src/DbExtensions/Mapper.cs ================================================ // Copyright 2010-2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections.Generic; using System.Data.Common; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Text; namespace DbExtensions; #nullable enable abstract partial class Mapper { internal static readonly char _pathSeparator = '$'; Node? _rootNode; MappingContext? _mappingContext; public TextWriter? Log { get; set; } public bool SingleResult { get; set; } protected MappingContext MappingContext { get { if (_mappingContext is null) { _mappingContext = new() { Log = Log, SingleResult = SingleResult }; InitializeMappingContext2(_mappingContext); } return _mappingContext; } } protected abstract bool CanUseConstructorMapping { get; } protected Mapper() { } void ReadMapping(DbDataReader record, Node rootNode) { var groups = (from i in Enumerable.Range(0, record.FieldCount) let columnName = record.GetName(i) let path = columnName.Split(_pathSeparator) let property = (path.Length == 1) ? columnName : path[^1] let assoc = (path.Length == 1) ? String.Empty : path[^2] let parent = (path.Length <= 2) ? String.Empty : path[^3] let propertyInfo = new { ColumnOrdinal = i, PropertyName = property } group propertyInfo by new { depth = path.Length - 1, parent, assoc } into t orderby t.Key.depth, t.Key.parent, t.Key.assoc select new MapGroup( t.Key.depth, t.Key.assoc, t.Key.parent, t.ToDictionary(p => p.ColumnOrdinal, p => p.PropertyName))) .ToArray(); var topGroup = groups.Where(m => m.Depth == 0).SingleOrDefault() ?? new MapGroup(0, String.Empty, String.Empty, new Dictionary()); ReadMapping(record, groups, topGroup, rootNode); } void ReadMapping(DbDataReader record, MapGroup[] groups, MapGroup currentGroup, Node instance) { var constructorParameters = new Dictionary(); var unmapped = new Dictionary(); var unmappedGroups = new Dictionary(); // simple properties foreach (var pair in currentGroup.Properties) { var propertyName = pair.Value; var columnOrdinal = pair.Key; var property = CreateSimpleProperty(instance, propertyName, columnOrdinal); if (property is not null) { instance.Properties.Add(property); continue; } if (UInt32.TryParse(propertyName, out var paramIndex)) { if (!constructorParameters.TryAdd(paramIndex, new MapParam(columnOrdinal))) { ThrowDuplicateConstructorArgument(paramIndex, columnOrdinal, record); } } else { unmapped.Add(propertyName, columnOrdinal); this.Log?.WriteLine($"-- WARNING: Couldn't find property '{propertyName}' on type '{instance.TypeName}'. Ignoring column."); } } // complex properties foreach (var nextLevel in groups .Where(m => m.Depth == currentGroup.Depth + 1 && m.Parent == currentGroup.Name)) { var propertyName = nextLevel.Name; var property = CreateComplexProperty(instance, propertyName); if (property is not null) { ReadMapping(record, groups, nextLevel, property); instance.Properties.Add(property); continue; } if (UInt32.TryParse(propertyName, out var paramIndex)) { if (!constructorParameters.TryAdd(paramIndex, new MapParam(nextLevel))) { ThrowDuplicateConstructorArgument(paramIndex, default, record); } } else { unmappedGroups.Add(propertyName, nextLevel); this.Log?.WriteLine($"-- WARNING: Couldn't find property '{propertyName}' on type '{instance.TypeName}'. Ignoring column(s)."); } } if (!this.CanUseConstructorMapping) { return; } var constructors = instance .GetConstructors(BindingFlags.Public | BindingFlags.Instance); if (constructorParameters.Count > 0) { // choose constructor based on positional arguments var ctor = ChooseConstructor(constructors, instance, constructorParameters.Count); var parameters = ctor.GetParameters(); var i = -1; foreach (var pair in constructorParameters.OrderBy(p => p.Key)) { i++; var paramIndex = pair.Key; var mapParam = pair.Value; var param = parameters[i]; Node paramNode; if (mapParam.ColumnOrdinal.HasValue) { paramNode = CreateParameterNode(mapParam.ColumnOrdinal.Value, param); } else { paramNode = CreateParameterNode(param); ReadMapping(record, groups, mapParam.Group!, paramNode); } if (!instance.ConstructorParameters.TryAdd(paramIndex, paramNode)) { ThrowDuplicateConstructorArgument(param, mapParam.ColumnOrdinal, record); } } instance.Constructor = ctor; } else { ParameterInfo[] parameters; if (constructors.Length == 1 && (parameters = constructors[0].GetParameters()).Length > 0) { // if there's a single constructor, try to bind unmaped // columns to constructor parameters by name foreach (var param in parameters) { var paramIndex = (uint)param.Position; if (unmapped.TryGetValue(param.Name!, out var columnOrdinal)) { var paramNode = CreateParameterNode(columnOrdinal, param); if (!instance.ConstructorParameters.TryAdd(paramIndex, paramNode)) { ThrowDuplicateConstructorArgument(param, columnOrdinal, record); } continue; } var property = instance.Properties .FirstOrDefault(p => !p.IsComplex && p.PropertyName == param.Name); if (property is not null) { var paramNode = CreateParameterNode(property.ColumnOrdinal, param); instance.Properties.Remove(property); if (!instance.ConstructorParameters.TryAdd(paramIndex, paramNode)) { ThrowDuplicateConstructorArgument(param, paramNode.ColumnOrdinal, record); } continue; } if (unmappedGroups.TryGetValue(param.Name!, out var group)) { var paramNode = CreateParameterNode(param); ReadMapping(record, groups, group, paramNode); if (!instance.ConstructorParameters.TryAdd(paramIndex, paramNode)) { ThrowDuplicateConstructorArgument(param, default, record); } } } if (parameters.Length != instance.ConstructorParameters.Count) { throw new InvalidOperationException( $"There are missing arguments for constructor with {parameters.Length} parameter(s) for type '{instance.TypeName}'."); } instance.Constructor = constructors[0]; } } } [DoesNotReturn] static void ThrowDuplicateConstructorArgument(uint paramIndex, int? columnOrdinal, DbDataReader record) { var message = new StringBuilder(); message.Append($"Already specified a positional argument {paramIndex}"); if (columnOrdinal.HasValue) { message.Append($" ('{record.GetName(columnOrdinal.Value)}')"); } message.Append('.'); throw new InvalidOperationException(message.ToString()); } [DoesNotReturn] static void ThrowDuplicateConstructorArgument(ParameterInfo param, int? columnOrdinal, DbDataReader record) { var message = new StringBuilder(); message.Append($"Already specified an argument for parameter '{param.Name}'"); if (columnOrdinal.HasValue) { message.Append($" ('{record.GetName(columnOrdinal.Value)}')"); } message.Append('.'); throw new InvalidOperationException(message.ToString()); } private protected Node GetRootNode(DbDataReader record) { if (_rootNode is null) { var node = CreateRootNode(); ReadMapping(record, node); _rootNode = node; } return _rootNode; } partial void InitializeMappingContext2(MappingContext context); protected abstract Node CreateRootNode(); protected abstract Node? CreateSimpleProperty(Node container, string propertyName, int columnOrdinal); protected abstract Node? CreateComplexProperty(Node container, string propertyName); protected abstract Node CreateParameterNode(ParameterInfo paramInfo); protected abstract Node CreateParameterNode(int columnOrdinal, ParameterInfo paramInfo); static ConstructorInfo ChooseConstructor(ConstructorInfo[] constructors, Node node, int parameterLength) { constructors = constructors .Where(c => c.GetParameters().Length == parameterLength) .ToArray(); if (constructors.Length == 0) { throw new InvalidOperationException( $"Couldn't find a public constructor with {parameterLength} parameter(s) for type '{node.TypeName}'."); } if (constructors.Length > 1) { throw new InvalidOperationException( $"Found more than one public constructors with {parameterLength} parameter(s) for type '{node.TypeName}'. Please use another constructor."); } return constructors[0]; } sealed class MapGroup(int depth, string name, string parent, Dictionary properties) { public readonly int Depth = depth; public readonly string Name = name; public readonly string Parent = parent; public readonly Dictionary Properties = properties; } readonly struct MapParam { public readonly int? ColumnOrdinal; public readonly MapGroup? Group; public MapParam(int columnOrdinal) { this.ColumnOrdinal = columnOrdinal; this.Group = null; } public MapParam(MapGroup group) { this.ColumnOrdinal = null; this.Group = group; } } } sealed partial class MappingContext { public TextWriter? Log; public bool SingleResult; } abstract class Node { Dictionary? _constructorParameters; List? _properties; public abstract bool IsComplex { get; } public abstract string? PropertyName { get; } public abstract int ColumnOrdinal { get; } public abstract string TypeName { get; } public ConstructorInfo? Constructor { get; internal set; } public Dictionary ConstructorParameters => _constructorParameters ??= new Dictionary(); public List Properties => _properties ??= new List(); public bool HasConstructorParameters => _constructorParameters?.Count > 0; public bool HasProperties => _properties?.Count > 0; public abstract ConstructorInfo[] GetConstructors(BindingFlags bindingAttr); } ================================================ FILE: src/DbExtensions/Metadata/Accessors.cs ================================================ // Copyright 2016-2022 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #region Based on code from .NET Framework #endregion using System; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; namespace DbExtensions.Metadata; delegate V DGet(T t); delegate void DSet(T t, V v); delegate void DRSet(ref T t, V v); static class FieldAccessor { [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static MetaAccessor Create(Type objectType, FieldInfo fi) { if (!fi.ReflectedType.IsAssignableFrom(objectType)) { throw Error.InvalidFieldInfo(objectType, fi.FieldType, fi); } Delegate dget = null; Delegate drset = null; if (!objectType.IsGenericType) { var mget = new DynamicMethod( "xget_" + fi.Name, fi.FieldType, [objectType], true); var gen = mget.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, fi); gen.Emit(OpCodes.Ret); dget = mget.CreateDelegate(typeof(DGet<,>).MakeGenericType(objectType, fi.FieldType)); var mset = new DynamicMethod( "xset_" + fi.Name, typeof(void), [objectType.MakeByRefType(), fi.FieldType], true); gen = mset.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); if (!objectType.IsValueType) { gen.Emit(OpCodes.Ldind_Ref); } gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Stfld, fi); gen.Emit(OpCodes.Ret); drset = mset.CreateDelegate(typeof(DRSet<,>).MakeGenericType(objectType, fi.FieldType)); } return (MetaAccessor)Activator.CreateInstance( typeof(Accessor<,>).MakeGenericType(objectType, fi.FieldType), BindingFlags.Instance | BindingFlags.NonPublic, null, [fi, dget, drset], null); } sealed class Accessor : MetaAccessor { readonly DGet _dget; readonly DRSet _drset; readonly FieldInfo _fi; internal Accessor(FieldInfo fi, DGet dget, DRSet drset) { _fi = fi; _dget = dget; _drset = drset; } public override V GetValue(T instance) { if (_dget is not null) { return _dget.Invoke(instance); } return (V)_fi.GetValue(instance); } public override void SetValue(ref T instance, V value) { if (_drset is not null) { _drset.Invoke(ref instance, value); } else { _fi.SetValue(instance, value); } } } } static class PropertyAccessor { internal static MetaAccessor Create(Type objectType, PropertyInfo pi, MetaAccessor storageAccessor) { var dset = default(Delegate); var drset = default(Delegate); var dgetType = typeof(DGet<,>).MakeGenericType(objectType, pi.PropertyType); var getMethod = pi.GetGetMethod(true); var dget = Delegate.CreateDelegate(dgetType, getMethod, true) ?? throw Error.CouldNotCreateAccessorToProperty(objectType, pi.PropertyType, pi); if (pi.CanWrite) { if (!objectType.IsValueType) { dset = Delegate.CreateDelegate(typeof(DSet<,>).MakeGenericType(objectType, pi.PropertyType), pi.GetSetMethod(true), true); } else { var mset = new DynamicMethod( "xset_" + pi.Name, typeof(void), [objectType.MakeByRefType(), pi.PropertyType], true); var gen = mset.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldind_Ref); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Call, pi.GetSetMethod(true)); gen.Emit(OpCodes.Ret); drset = mset.CreateDelegate(typeof(DRSet<,>).MakeGenericType(objectType, pi.PropertyType)); } } var saType = (storageAccessor is not null) ? storageAccessor.Type : pi.PropertyType; return (MetaAccessor)Activator.CreateInstance( typeof(Accessor<,,>).MakeGenericType(objectType, pi.PropertyType, saType), BindingFlags.Instance | BindingFlags.NonPublic, null, [pi, dget, dset, drset, storageAccessor], null); } internal static MetaCollectionAccessor CreateCollection(Type objectType, Type elementType, PropertyInfo pi) { var propAccessor = Create(objectType, pi, null); var colType = pi.PropertyType; var addMethod = colType.GetMethod("Add", BindingFlags.Instance | BindingFlags.Public, null, [elementType], null) ?? throw new InvalidOperationException($"Couldn't find a public 'Add' method on '{colType.FullName}'."); var addFn = Delegate.CreateDelegate(typeof(Action<,>) .MakeGenericType(colType, elementType), addMethod); return (MetaCollectionAccessor)Activator.CreateInstance( typeof(MetaCollectionAccessor<,,>).MakeGenericType(objectType, colType, elementType), BindingFlags.Instance | BindingFlags.NonPublic, null, [propAccessor, addFn], null)!; } sealed class Accessor : MetaAccessor where V2 : V { readonly PropertyInfo _pi; readonly DGet _dget; readonly DSet _dset; readonly DRSet _drset; readonly MetaAccessor _storage; internal Accessor(PropertyInfo pi, DGet dget, DSet dset, DRSet drset, MetaAccessor storage) { _pi = pi; _dget = dget; _dset = dset; _drset = drset; _storage = storage; } public override V GetValue(T instance) => _dget.Invoke(instance); public override void SetValue(ref T instance, V value) { if (_dset is not null) { _dset.Invoke(instance, value); } else if (_drset is not null) { _drset.Invoke(ref instance, value); } else if (_storage is not null) { _storage.SetValue(ref instance, (V2)value); } else { throw Error.UnableToAssignValueToReadonlyProperty(_pi); } } } } ================================================ FILE: src/DbExtensions/Metadata/AttributedMetaModel.cs ================================================ // Copyright 2016-2022 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #region Based on code from .NET Framework #endregion using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Reflection; using System.Threading; namespace DbExtensions.Metadata; sealed class AttributedMetaModel : MetaModel { readonly ReaderWriterLock _lock = new(); readonly Dictionary _metaTypes = new(); readonly Dictionary _metaTables = new(); internal override MappingSource MappingSource { get; } internal override Type ContextType { get; } internal override string DatabaseName { get; } internal AttributedMetaModel(MappingSource mappingSource, Type contextType) { this.MappingSource = mappingSource; this.ContextType = contextType; var das = (DatabaseAttribute[])this.ContextType.GetCustomAttributes(typeof(DatabaseAttribute), false); this.DatabaseName = (das is not null && das.Length > 0) ? das[0].Name : this.ContextType.Name; } public override IEnumerable GetTables() { _lock.AcquireReaderLock(Timeout.Infinite); try { return _metaTables.Values .Where(x => x is not null) .Distinct(); } finally { _lock.ReleaseReaderLock(); } } public override MetaTable GetTable(Type rowType, MetaTableConfiguration config) { ArgumentNullException.ThrowIfNull(rowType); MetaTable table; _lock.AcquireReaderLock(Timeout.Infinite); try { if (_metaTables.TryGetValue(rowType, out table)) { return table; } } finally { _lock.ReleaseReaderLock(); } _lock.AcquireWriterLock(Timeout.Infinite); try { table = GetTableNoLocks(rowType, config); } finally { _lock.ReleaseWriterLock(); } return table; } internal MetaTable GetTableNoLocks(Type rowType, MetaTableConfiguration config) { MetaTable table; if (!_metaTables.TryGetValue(rowType, out table)) { var root = GetRoot(rowType) ?? rowType; var attrs = (TableAttribute[])root.GetCustomAttributes(typeof(TableAttribute), true); if (attrs.Length == 0) { _metaTables.Add(rowType, null); } else { if (!_metaTables.TryGetValue(root, out table)) { table = new AttributedMetaTable(this, attrs[0], root, config); foreach (var mt in table.RowType.InheritanceTypes) { _metaTables.Add(mt.Type, table); } } // catch case of derived type that is not part of inheritance if (table.RowType.GetInheritanceType(rowType) is null) { _metaTables.Add(rowType, null); return null; } } } return table; } static Type GetRoot(Type derivedType) { while (derivedType is not null && derivedType != typeof(object)) { var attrs = (TableAttribute[])derivedType.GetCustomAttributes(typeof(TableAttribute), false); if (attrs.Length > 0) { return derivedType; } derivedType = derivedType.BaseType; } return null; } public override MetaType GetMetaType(Type type, MetaTableConfiguration config) { ArgumentNullException.ThrowIfNull(type); MetaType mtype = null; _lock.AcquireReaderLock(Timeout.Infinite); try { if (_metaTypes.TryGetValue(type, out mtype)) { return mtype; } } finally { _lock.ReleaseReaderLock(); } // Attributed meta model allows us to learn about tables we did not // statically know about var tab = GetTable(type, config); if (tab is not null) { return tab.RowType.GetInheritanceType(type); } _lock.AcquireWriterLock(Timeout.Infinite); try { if (!_metaTypes.TryGetValue(type, out mtype)) { mtype = new UnmappedType(this, type); _metaTypes.Add(type, mtype); } } finally { _lock.ReleaseWriterLock(); } return mtype; } } sealed class AttributedMetaTable : MetaTable { public override MetaModel Model { get; } public override string TableName { get; } public override MetaType RowType { get; } internal MetaTableConfiguration Configuration { get; private set; } internal AttributedMetaTable(AttributedMetaModel model, TableAttribute attr, Type rowType, MetaTableConfiguration config) { // set this first this.Configuration = new MetaTableConfiguration(config); this.Model = model; this.TableName = String.IsNullOrEmpty(attr.Name) ? rowType.Name : attr.Name; this.RowType = new AttributedRootType(model, this, rowType); } } sealed class AttributedRootType : AttributedMetaType { readonly Dictionary _types; readonly Dictionary _codeMap; internal override bool HasInheritance => _types is not null; internal override ReadOnlyCollection InheritanceTypes { get; } internal override MetaType InheritanceDefault { get; } internal AttributedRootType(AttributedMetaModel model, AttributedMetaTable table, Type type) : base(model, table, type, null) { // check for inheritance and create all other types var inheritanceInfo = (InheritanceMappingAttribute[]) type.GetCustomAttributes(typeof(InheritanceMappingAttribute), true); if (inheritanceInfo.Length > 0) { if (this.Discriminator is null) { throw Error.NoDiscriminatorFound(type); } if (!MappingSystem.IsSupportedDiscriminatorType(this.Discriminator.Type)) { throw Error.DiscriminatorClrTypeNotSupported(this.Discriminator.DeclaringType.Name, this.Discriminator.Name, this.Discriminator.Type); } _types = new Dictionary(); _types.Add(type, this); // add self _codeMap = new Dictionary(); // initialize inheritance types foreach (var attr in inheritanceInfo) { if (!type.IsAssignableFrom(attr.Type)) { throw Error.InheritanceTypeDoesNotDeriveFromRoot(attr.Type, type); } if (attr.Type.IsAbstract) { throw Error.AbstractClassAssignInheritanceDiscriminator(attr.Type); } var mt = CreateInheritedType(type, attr.Type); if (attr.Code is null) { throw Error.InheritanceCodeMayNotBeNull(); } if (mt._inheritanceCode is not null) { throw Error.InheritanceTypeHasMultipleDiscriminators(attr.Type); } //var codeValue = DBConvert.ChangeType(*/attr.Code/*, this.Discriminator.Type); var codeValue = attr.Code; foreach (var d in _codeMap.Keys) { // if the keys are equal, or if they are both strings containing only spaces // they are considered equal if ((codeValue.GetType() == typeof(string) && ((string)codeValue).Trim().Length == 0 && d.GetType() == typeof(string) && ((string)d).Trim().Length == 0) || Object.Equals(d, codeValue)) { throw Error.InheritanceCodeUsedForMultipleTypes(codeValue); } } mt._inheritanceCode = codeValue; _codeMap.Add(codeValue, mt); if (attr.IsDefault) { if (this.InheritanceDefault is not null) { throw Error.InheritanceTypeHasMultipleDefaults(type); } this.InheritanceDefault = mt; } } if (this.InheritanceDefault is null) { throw Error.InheritanceHierarchyDoesNotDefineDefault(type); } } if (_types is not null) { this.InheritanceTypes = _types.Values.ToList().AsReadOnly(); } else { this.InheritanceTypes = new List(1) { this }.AsReadOnly(); } Validate(); } void Validate() { var memberToColumn = new Dictionary(); foreach (var type in this.InheritanceTypes) { if (type != this) { var attrs = (TableAttribute[])type.Type.GetCustomAttributes(typeof(TableAttribute), false); if (attrs.Length > 0) { throw Error.InheritanceSubTypeIsAlsoRoot(type.Type); } } foreach (var mem in type.PersistentDataMembers) { if (mem.IsDeclaredBy(type)) { if (mem.IsDiscriminator && !this.HasInheritance) { throw Error.NonInheritanceClassHasDiscriminator(type); } if (!mem.IsAssociation) { // validate that no database column is mapped twice if (!String.IsNullOrEmpty(mem.MappedName)) { var dn = InheritanceRules.DistinguishedMemberName(mem.Member); if (memberToColumn.TryGetValue(dn, out var column)) { if (column != mem.MappedName) { throw Error.MemberMappedMoreThanOnce(mem.Member.Name); } } else { memberToColumn.Add(dn, mem.MappedName); } } } } } } } AttributedMetaType CreateInheritedType(Type root, Type type) { MetaType metaType; if (!_types.TryGetValue(type, out metaType)) { metaType = new AttributedMetaType(this.Model, this.Table, type, this); _types.Add(type, metaType); if (type != root && type.BaseType != typeof(object)) { CreateInheritedType(root, type.BaseType); } } return (AttributedMetaType)metaType; } internal override MetaType GetInheritanceType(Type type) { if (type == this.Type) { return this; } var metaType = default(MetaType); _types?.TryGetValue(type, out metaType); return metaType; } } class AttributedMetaType : MetaType { Dictionary _dataMemberMap; ReadOnlyCollection _dataMembers; ReadOnlyCollection _associations; MetaDataMember _dbGeneratedIdentity; MetaDataMember _version; bool _inheritanceBaseSet; MetaType _inheritanceBase; internal object _inheritanceCode; MetaDataMember _discriminator; ReadOnlyCollection _derivedTypes; readonly object _locktarget = new(); // Hold locks on private object rather than public MetaType. public override MetaModel Model { get; } public override MetaTable Table { get; } public override Type Type { get; } public override MetaDataMember DBGeneratedIdentityMember => _dbGeneratedIdentity; public override MetaDataMember VersionMember => _version; public override string Name => Type.Name; public override bool IsEntity => Table?.RowType.IdentityMembers.Count > 0; public override bool CanInstantiate => !Type.IsAbstract && (this == InheritanceRoot || HasInheritanceCode); public override bool HasUpdateCheck => PersistentDataMembers.Any(m => m.UpdateCheck != UpdateCheck.Never); public override ReadOnlyCollection DataMembers => _dataMembers; public override ReadOnlyCollection PersistentDataMembers { get; } public override ReadOnlyCollection IdentityMembers { get; } public override ReadOnlyCollection Associations { get { // LOCKING: Associations are late-expanded so that cycles are broken. if (_associations is null) { lock (_locktarget) { _associations ??= DataMembers.Where(m => m.IsAssociation) .Select(m => m.Association) .ToList() .AsReadOnly(); } } return _associations; } } internal override MetaType InheritanceRoot { get; } internal override MetaDataMember Discriminator => _discriminator; internal override bool HasInheritance => InheritanceRoot.HasInheritance; internal override bool HasInheritanceCode => InheritanceCode is not null; internal override object InheritanceCode => _inheritanceCode; internal override MetaType InheritanceDefault => InheritanceRoot.InheritanceDefault; internal override bool IsInheritanceDefault => InheritanceDefault == this; internal override ReadOnlyCollection InheritanceTypes => InheritanceRoot.InheritanceTypes; internal override MetaType InheritanceBase { get { // LOCKING: Cannot initialize at construction if (!_inheritanceBaseSet && _inheritanceBase is null) { lock (_locktarget) { if (_inheritanceBase is null) { _inheritanceBase = InheritanceBaseFinder.FindBase(this); _inheritanceBaseSet = true; } } } return _inheritanceBase; } } internal override ReadOnlyCollection DerivedTypes { get { // LOCKING: Cannot initialize at construction because derived types // won't exist yet. if (_derivedTypes is null) { lock (_locktarget) { if (_derivedTypes is null) { var dTypes = new List(); foreach (var mt in InheritanceTypes) { if (mt.Type.BaseType == Type) { dTypes.Add(mt); } } _derivedTypes = dTypes.AsReadOnly(); } } } return _derivedTypes; } } internal AttributedMetaType(MetaModel model, MetaTable table, Type type, MetaType inheritanceRoot) { this.Model = model; this.Table = table; this.Type = type; this.InheritanceRoot = inheritanceRoot ?? this; // Not lazy-loading to simplify locking and enhance performance // (because no lock will be required for the common read scenario). InitDataMembers(); this.IdentityMembers = this.DataMembers.Where(m => m.IsPrimaryKey).ToList().AsReadOnly(); this.PersistentDataMembers = this.DataMembers.Where(m => m.IsPersistent).ToList().AsReadOnly(); } void ValidatePrimaryKeyMember(MetaDataMember mm) { //if the type is a sub-type, no member declared in the type can be primary key if (mm.IsPrimaryKey && this.InheritanceRoot != this && mm.Member.DeclaringType == this.Type) { throw (Error.PrimaryKeyInSubTypeNotSupported(this.Type.Name, mm.Name)); } } void InitDataMembers() { if (_dataMembers is null) { _dataMemberMap = new Dictionary(); InitDataMembersImpl(this.Type); _dataMembers = new List(_dataMemberMap.Values).AsReadOnly(); } } void InitDataMembersImpl(Type containerType, MetaComplexProperty containerCp = null) { var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy; var fis = TypeSystem.GetAllFields(containerType, flags) .ToArray(); if (fis is not null) { for (int i = 0, n = fis.Length; i < n; i++) { var fi = fis[i]; var mm = new AttributedMetaDataMember(this, fi, _dataMemberMap.Count, null); ValidatePrimaryKeyMember(mm); // must be public or persistent if (!mm.IsPersistent && !fi.IsPublic) { continue; } _dataMemberMap.Add(new MetaPosition(fi), mm); // must be persistent for the rest if (!mm.IsPersistent) { continue; } InitSpecialMember(mm); } } var pis = TypeSystem.GetAllProperties(containerType, flags) .ToArray(); if (pis is not null) { for (int i = 0, n = pis.Length; i < n; i++) { var pi = pis[i]; var mm = new AttributedMetaDataMember(this, pi, _dataMemberMap.Count, containerCp); ValidatePrimaryKeyMember(mm); // must be public or persistent var isPublic = (pi.CanRead && pi.GetGetMethod(false) is not null) && (!pi.CanWrite || pi.GetSetMethod(false) is not null); if (!mm.IsPersistent && !isPublic) { continue; } if (!mm.IsPersistent) { var cpAttr = (ComplexPropertyAttribute)Attribute.GetCustomAttribute(pi, typeof(ComplexPropertyAttribute)); if (cpAttr is not null) { var complexPropType = pi.PropertyType; if (!complexPropType.IsClass) { throw new InvalidOperationException("A persistent complex property must be a class."); } if (complexPropType.IsAbstract) { throw new InvalidOperationException("A persistent complex property cannot be an abstract type."); } var metaCp = new MetaComplexProperty(this, pi, cpAttr, containerCp); InitDataMembersImpl(complexPropType, metaCp); continue; } } _dataMemberMap.Add(new MetaPosition(pi), mm); // must be persistent for the rest if (!mm.IsPersistent) { continue; } InitSpecialMember(mm); } } } void InitSpecialMember(MetaDataMember mm) { // Can only have one auto gen member that is also an identity member, // except if that member is a computed column (since they are implicitly auto gen) if (mm.IsDbGenerated && mm.IsPrimaryKey && String.IsNullOrEmpty(mm.Expression)) { if (_dbGeneratedIdentity is not null) { throw Error.TwoMembersMarkedAsPrimaryKeyAndDBGenerated(mm.Member, _dbGeneratedIdentity.Member); } _dbGeneratedIdentity = mm; } if (mm.IsPrimaryKey && !MappingSystem.IsSupportedIdentityType(mm.Type)) { throw Error.IdentityClrTypeNotSupported(mm.DeclaringType, mm.Name, mm.Type); } if (mm.IsVersion) { if (_version is not null) { throw Error.TwoMembersMarkedAsRowVersion(mm.Member, _version.Member); } _version = mm; } if (mm.IsDiscriminator) { if (_discriminator is not null) { throw Error.TwoMembersMarkedAsInheritanceDiscriminator(mm.Member, _discriminator.Member); } _discriminator = mm; } } public override MetaDataMember GetDataMember(MemberInfo mi) { ArgumentNullException.ThrowIfNull(mi); if (_dataMemberMap.TryGetValue(new MetaPosition(mi), out var mm)) { return mm; } // DON'T look to see if we are trying to get a member from an inherited type. // The calling code should know to look in the inherited type. if (mi.DeclaringType.IsInterface) { throw Error.MappingOfInterfacesMemberIsNotSupported(mi.DeclaringType.Name, mi.Name); } // the member is not mapped in the base class throw Error.UnmappedClassMember(mi.DeclaringType.Name, mi.Name); } internal override MetaType GetInheritanceType(Type inheritanceType) { if (inheritanceType == this.Type) { return this; } return this.InheritanceRoot.GetInheritanceType(inheritanceType); } internal override MetaType GetTypeForInheritanceCode(object key) { if (this.InheritanceRoot.Discriminator.Type == typeof(string)) { var skey = (string)key; foreach (var mt in this.InheritanceRoot.InheritanceTypes) { if (String.Compare((string)mt.InheritanceCode, skey, StringComparison.OrdinalIgnoreCase) == 0) { return mt; } } } else { foreach (var mt in this.InheritanceRoot.InheritanceTypes) { if (Object.Equals(mt.InheritanceCode, key)) { return mt; } } } return null; } public override string ToString() => this.Name; } sealed class AttributedMetaDataMember : MetaDataMember { readonly Type _memberDeclaringType; bool _hasAccessors; MetaAccessor _accPublic; MetaAccessor _accPrivate; readonly IDataAttribute _attr; readonly ColumnAttribute _attrColumn; readonly AssociationAttribute _attrAssoc; AttributedMetaAssociation _assoc; readonly bool _isNullableType; readonly object _locktarget = new(); // Hold locks on private object rather than public MetaType. readonly MetaComplexProperty _containerCp; public override MetaType DeclaringType { get; } public override MemberInfo Member { get; } public override MemberInfo StorageMember { get; } public override string Name => Member.Name; public override int Ordinal { get; } public override Type Type { get; } public override Type ConvertToType => _attrColumn?.ConvertTo; public override bool IsPersistent => _attrColumn is not null || _attrAssoc is not null; public override bool IsAssociation => _attrAssoc is not null; public override bool IsPrimaryKey => _attrColumn?.IsPrimaryKey ?? false; public override bool IsVersion => _attrColumn?.IsVersion ?? false; public override string DbType => _attrColumn?.DbType; public override string Expression => _attrColumn?.Expression; public override UpdateCheck UpdateCheck => _attrColumn?.UpdateCheck ?? UpdateCheck.Never; public override string MappedName { get { var n = _attrColumn?.Name ?? _attrAssoc?.Name ?? Member.Name; if (_containerCp is not null) { return _containerCp.FullMappedName + _containerCp.Separator + n; } return n; } } public override string QueryPath => (_containerCp is not null) ? _containerCp.QueryPath + MetaComplexProperty.QueryPathSeparator + Name : Name; internal override bool IsDiscriminator => _attrColumn?.IsDiscriminator ?? false; /// /// Returns true if the member is explicitly marked as auto gen, or if the /// member is computed or generated by the database server. /// public override bool IsDbGenerated { get { return _attrColumn is not null && (_attrColumn.IsDbGenerated || !String.IsNullOrEmpty(_attrColumn.Expression)) || IsVersion; } } public override MetaAccessor MemberAccessor { get { InitAccessors(); return _accPublic; } } public override MetaAccessor StorageAccessor { get { InitAccessors(); return _accPrivate; } } public override bool CanBeNull { get { if (_attrColumn is null) { return true; } if (!_attrColumn.CanBeNullSet) { return _isNullableType || !Type.IsValueType; } return _attrColumn.CanBeNull; } } public override AutoSync AutoSync { get { if (_attrColumn is not null) { // auto-gen keys are always and only synced on insert if (IsDbGenerated && IsPrimaryKey) { return AutoSync.OnInsert; } // if the user has explicitly set it, use their value if (_attrColumn.AutoSync != AutoSync.Default) { return _attrColumn.AutoSync; } // database generated members default to always if (IsDbGenerated) { return AutoSync.Always; } } return AutoSync.Never; } } public override MetaAssociation Association { get { if (IsAssociation) { // LOCKING: This deferral isn't an optimization. It can't be done in the constructor // because there may be loops in the association graph. if (_assoc is null) { lock (_locktarget) { _assoc ??= new AttributedMetaAssociation(this, _attrAssoc); } } } return _assoc; } } internal AttributedMetaDataMember(AttributedMetaType metaType, MemberInfo mi, int ordinal, MetaComplexProperty containerCp) { _memberDeclaringType = mi.DeclaringType; this.DeclaringType = metaType; this.Member = mi; this.Ordinal = ordinal; this.Type = TypeSystem.GetMemberType(mi); _isNullableType = TypeSystem.IsNullableType(this.Type); _attrColumn = (ColumnAttribute)Attribute.GetCustomAttribute(mi, typeof(ColumnAttribute)); _attrAssoc = (AssociationAttribute)Attribute.GetCustomAttribute(mi, typeof(AssociationAttribute)); _attr = (_attrColumn is not null) ? (IDataAttribute)_attrColumn : (IDataAttribute)_attrAssoc; if (_attr is not null && _attr.Storage is not null) { var mis = mi.DeclaringType.GetMember(_attr.Storage, BindingFlags.Instance | BindingFlags.NonPublic); if (mis is null || mis.Length != 1) { throw Error.BadStorageProperty(_attr.Storage, mi.DeclaringType, mi.Name); } this.StorageMember = mis[0]; } var storageType = (this.StorageMember is not null) ? TypeSystem.GetMemberType(this.StorageMember) : this.Type; if (_attrColumn is not null && _attrColumn.IsDbGenerated && _attrColumn.IsPrimaryKey) { // auto-gen identities must be synced on insert if ((_attrColumn.AutoSync != AutoSync.Default) && (_attrColumn.AutoSync != AutoSync.OnInsert)) { throw Error.IncorrectAutoSyncSpecification(mi.Name); } } _containerCp = containerCp; } void InitAccessors() { if (!_hasAccessors) { var association = this.Association; lock (_locktarget) { if (!_hasAccessors) { if (association is { IsMany: true }) { var elementType = association.OtherType.Type; var pi = (PropertyInfo)this.Member; _accPublic = _accPrivate = PropertyAccessor.CreateCollection(this.Member.ReflectedType, elementType, pi); } else if (this.StorageMember is not null) { _accPrivate = MakeMemberAccessor(this.Member.ReflectedType, this.StorageMember, null); _accPublic = MakeMemberAccessor(this.Member.ReflectedType, this.Member, _accPrivate); } else { _accPublic = _accPrivate = MakeMemberAccessor(this.Member.ReflectedType, this.Member, null); } _hasAccessors = true; } } } } static MetaAccessor MakeMemberAccessor(Type accessorType, MemberInfo mi, MetaAccessor storage) { var fi = mi as FieldInfo; MetaAccessor acc; if (fi is not null) { acc = FieldAccessor.Create(accessorType, fi); } else { var pi = (PropertyInfo)mi; acc = PropertyAccessor.Create(accessorType, pi, storage); } return acc; } public override object GetValueForDatabase(object instance) { if (_containerCp is not null) { instance = _containerCp.GetValueFromRoot(instance); if (instance is null) { return null; } } return base.GetValueForDatabase(instance); } public override bool IsDeclaredBy(MetaType declaringMetaType) { ArgumentNullException.ThrowIfNull(declaringMetaType); return declaringMetaType.Type == _memberDeclaringType; } public override string ToString() => this.DeclaringType.ToString() + ":" + this.Member.ToString(); } sealed class MetaComplexProperty { internal static readonly string QueryPathSeparator = Mapper._pathSeparator.ToString(); readonly ComplexPropertyAttribute _cpAttr; MetaAccessor _accPublic; bool _hasAccessors; readonly object _locktarget = new(); public PropertyInfo Member { get; } public string Separator => _cpAttr.Separator; public string MappedName => _cpAttr.Name ?? Member.Name; public string FullMappedName => (Parent is not null) ? Parent.FullMappedName + Parent.Separator + MappedName : MappedName; public string QueryPath => (Parent is not null) ? Parent.QueryPath + QueryPathSeparator + Member.Name : Member.Name; public MetaComplexProperty Parent { get; } public MetaAccessor MemberAccessor { get { InitAccessors(); return _accPublic; } } public MetaComplexProperty(AttributedMetaType metaType, PropertyInfo member, ComplexPropertyAttribute cpAttr, MetaComplexProperty parent) { this.Member = member; _cpAttr = cpAttr; this.Parent = parent; string defaultSeparator; if (cpAttr.Separator is null && (defaultSeparator = ((AttributedMetaTable)metaType.Table).Configuration.DefaultComplexPropertySeparator) is not null) { _cpAttr = new ComplexPropertyAttribute(_cpAttr) { Separator = defaultSeparator }; } } void InitAccessors() { if (!_hasAccessors) { lock (_locktarget) { if (!_hasAccessors) { _accPublic = PropertyAccessor.Create(this.Member.ReflectedType, this.Member, null); _hasAccessors = true; } } } } public object GetValueFromRoot(object root) { var cpStack = new Stack(); cpStack.Push(this); var current = this; while (current.Parent is not null) { cpStack.Push(current.Parent); current = current.Parent; } object obj = root; while (cpStack.Count > 0) { var cp = cpStack.Pop(); obj = cp.MemberAccessor.GetBoxedValue(obj); if (obj is null) { break; } } return obj; } } sealed class AttributedMetaAssociation : MetaAssociationImpl { public override MetaType OtherType { get; } public override MetaDataMember ThisMember { get; } public override MetaDataMember OtherMember { get; } public override ReadOnlyCollection ThisKey { get; } public override ReadOnlyCollection OtherKey { get; } public override bool ThisKeyIsPrimaryKey { get; } public override bool OtherKeyIsPrimaryKey { get; } public override bool IsMany { get; } public override bool IsForeignKey { get; } public override bool IsUnique { get; } public override bool IsNullable { get; } public override string DeleteRule { get; } public override bool DeleteOnNull { get; } internal AttributedMetaAssociation(AttributedMetaDataMember member, AssociationAttribute attr) { this.ThisMember = member; this.IsMany = TypeSystem.IsSequenceType(this.ThisMember.Type); var ot = (this.IsMany) ? TypeSystem.GetElementType(this.ThisMember.Type) : this.ThisMember.Type; this.OtherType = this.ThisMember.DeclaringType.Model.GetMetaType(ot, ((AttributedMetaTable)this.ThisMember.DeclaringType.Table).Configuration); this.ThisKey = (attr.ThisKey is not null) ? MakeKeys(this.ThisMember.DeclaringType, attr.ThisKey) : this.ThisMember.DeclaringType.IdentityMembers; this.OtherKey = (attr.OtherKey is not null) ? MakeKeys(this.OtherType, attr.OtherKey) : this.OtherType.IdentityMembers; this.ThisKeyIsPrimaryKey = AreEqual(this.ThisKey, this.ThisMember.DeclaringType.IdentityMembers); this.OtherKeyIsPrimaryKey = AreEqual(this.OtherKey, this.OtherType.IdentityMembers); this.IsForeignKey = attr.IsForeignKey; this.IsUnique = attr.IsUnique; this.DeleteRule = attr.DeleteRule; this.DeleteOnNull = attr.DeleteOnNull; // if any key members are not nullable, the association is not nullable foreach (var mm in this.ThisKey) { if (!mm.CanBeNull) { this.IsNullable = false; break; } } // validate DeleteOnNull specification if (this.DeleteOnNull == true) { if (!(this.IsForeignKey && !this.IsMany && !this.IsNullable)) { throw Error.InvalidDeleteOnNullSpecification(member); } } // validate the number of ThisKey columns is the same as the number of OtherKey columns if (this.ThisKey.Count != this.OtherKey.Count && this.ThisKey.Count > 0 && this.OtherKey.Count > 0) { throw Error.MismatchedThisKeyOtherKey(member.Name, member.DeclaringType.Name); } // determine reverse reference member foreach (var omm in this.OtherType.PersistentDataMembers) { var oattr = (AssociationAttribute)Attribute.GetCustomAttribute(omm.Member, typeof(AssociationAttribute)); if (oattr is null || omm == this.ThisMember) { continue; } if (attr.Name is not null && oattr.Name == attr.Name) { this.OtherMember = omm; break; } var otherMemberIsMany = TypeSystem.IsSequenceType(omm.Type); var otherMemberType = (otherMemberIsMany) ? TypeSystem.GetElementType(omm.Type) : omm.Type; if (member.DeclaringType.Type == otherMemberType) { this.OtherMember = omm; break; } } } } abstract class MetaAssociationImpl : MetaAssociation { /// /// Given a MetaType and a set of key fields, return the set of MetaDataMembers /// corresponding to the key. /// protected static ReadOnlyCollection MakeKeys(MetaType mtype, string keyFields) { var names = keyFields.Split(','); var members = new MetaDataMember[names.Length]; for (int i = 0; i < names.Length; i++) { names[i] = names[i].Trim(); var rmis = mtype.Type.GetMember(names[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (rmis is null || rmis.Length != 1) { throw Error.BadKeyMember(names[i], keyFields, mtype.Name); } members[i] = mtype.GetDataMember(rmis[0]); if (members[i] is null) { throw Error.BadKeyMember(names[i], keyFields, mtype.Name); } } return new List(members).AsReadOnly(); } /// /// Compare two sets of keys for equality. /// protected static bool AreEqual(IEnumerable key1, IEnumerable key2) { using (var e1 = key1.GetEnumerator()) { using (var e2 = key2.GetEnumerator()) { bool m1, m2; for (m1 = e1.MoveNext(), m2 = e2.MoveNext(); m1 && m2; m1 = e1.MoveNext(), m2 = e2.MoveNext()) { if (e1.Current != e2.Current) { return false; } } if (m1 != m2) { return false; } } } return true; } public override string ToString() => $"{this.ThisMember.DeclaringType.Name} ->{(this.IsMany ? "*" : null)} {this.OtherType.Name}"; } sealed class UnmappedType : MetaType { readonly static ReadOnlyCollection _emptyTypes = new List().AsReadOnly(); readonly static ReadOnlyCollection _emptyDataMembers = new List().AsReadOnly(); readonly static ReadOnlyCollection _emptyAssociations = new List().AsReadOnly(); Dictionary _dataMemberMap; ReadOnlyCollection _dataMembers; ReadOnlyCollection _inheritanceTypes; readonly object _locktarget = new(); // Hold locks on private object rather than public MetaType. public override MetaModel Model { get; } public override Type Type { get; } public override MetaTable Table => null; public override string Name => Type.Name; public override bool IsEntity => false; public override bool CanInstantiate => !Type.IsAbstract; public override MetaDataMember DBGeneratedIdentityMember => null; public override MetaDataMember VersionMember => null; internal override MetaDataMember Discriminator => null; public override bool HasUpdateCheck => false; public override ReadOnlyCollection DataMembers { get { InitDataMembers(); return _dataMembers; } } public override ReadOnlyCollection PersistentDataMembers => _emptyDataMembers; public override ReadOnlyCollection IdentityMembers { get { InitDataMembers(); return _dataMembers; } } public override ReadOnlyCollection Associations => _emptyAssociations; internal override ReadOnlyCollection InheritanceTypes { get { if (_inheritanceTypes is null) { lock (_locktarget) { _inheritanceTypes ??= new List(1) { this }.AsReadOnly(); } } return _inheritanceTypes; } } internal override ReadOnlyCollection DerivedTypes => _emptyTypes; internal override bool HasInheritance => false; internal override bool HasInheritanceCode => false; internal override object InheritanceCode => null; internal override MetaType InheritanceRoot => this; internal override MetaType InheritanceBase => null; internal override MetaType InheritanceDefault => null; internal override bool IsInheritanceDefault => false; internal UnmappedType(MetaModel model, Type type) { this.Model = model; this.Type = type; } internal override MetaType GetInheritanceType(Type inheritanceType) { if (inheritanceType == this.Type) { return this; } return null; } internal override MetaType GetTypeForInheritanceCode(object key) => null; public override MetaDataMember GetDataMember(MemberInfo mi) { ArgumentNullException.ThrowIfNull(mi); InitDataMembers(); if (_dataMemberMap is null) { lock (_locktarget) { if (_dataMemberMap is null) { var map = new Dictionary(); foreach (var mm in _dataMembers) { map.Add(InheritanceRules.DistinguishedMemberName(mm.Member), mm); } _dataMemberMap = map; } } } var dn = InheritanceRules.DistinguishedMemberName(mi); _dataMemberMap.TryGetValue(dn, out var mdm); return mdm; } void InitDataMembers() { if (_dataMembers is null) { lock (_locktarget) { if (_dataMembers is null) { var dMembers = new List(); var ordinal = 0; var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy; foreach (var fi in this.Type.GetFields(flags)) { var mm = new UnmappedDataMember(this, fi, ordinal); dMembers.Add(mm); ordinal++; } foreach (var pi in this.Type.GetProperties(flags)) { var mm = new UnmappedDataMember(this, pi, ordinal); dMembers.Add(mm); ordinal++; } _dataMembers = dMembers.AsReadOnly(); } } } } public override string ToString() => this.Name; } sealed class UnmappedDataMember : MetaDataMember { MetaAccessor _accPublic; readonly object _lockTarget = new(); public override MetaType DeclaringType { get; } public override MemberInfo Member { get; } public override int Ordinal { get; } public override Type Type { get; } public override Type ConvertToType { get; } public override MemberInfo StorageMember => Member; public override string Name => Member.Name; public override MetaAccessor MemberAccessor { get { InitAccessors(); return _accPublic; } } public override MetaAccessor StorageAccessor { get { InitAccessors(); return _accPublic; } } public override bool IsPersistent => false; public override bool IsAssociation => false; public override bool IsPrimaryKey => false; public override bool IsDbGenerated => false; public override bool IsVersion => false; internal override bool IsDiscriminator => false; public override bool CanBeNull => !Type.IsValueType || TypeSystem.IsNullableType(Type); public override string DbType => null; public override string Expression => null; public override string MappedName => Member.Name; public override UpdateCheck UpdateCheck => UpdateCheck.Never; public override AutoSync AutoSync => AutoSync.Never; public override MetaAssociation Association => null; internal UnmappedDataMember(MetaType declaringType, MemberInfo mi, int ordinal) { this.DeclaringType = declaringType; this.Member = mi; this.Ordinal = ordinal; this.Type = TypeSystem.GetMemberType(mi); } void InitAccessors() { if (_accPublic is null) { lock (_lockTarget) { _accPublic ??= MakeMemberAccessor(this.Member.ReflectedType, this.Member); } } } public override bool IsDeclaredBy(MetaType metaType) { ArgumentNullException.ThrowIfNull(metaType); return metaType.Type == this.Member.DeclaringType; } static MetaAccessor MakeMemberAccessor(Type accessorType, MemberInfo mi) { MetaAccessor acc; if (mi is FieldInfo fi) { acc = FieldAccessor.Create(accessorType, fi); } else { PropertyInfo pi = (PropertyInfo)mi; acc = PropertyAccessor.Create(accessorType, pi, null); } return acc; } } static class InheritanceBaseFinder { internal static MetaType FindBase(MetaType derivedType) { if (derivedType.Type == typeof(object)) { return null; } var clrType = derivedType.Type; // start var rootClrType = derivedType.InheritanceRoot.Type; // end MetaType metaType; while (true) { if (clrType == typeof(object) || clrType == rootClrType) { return null; } clrType = clrType.BaseType; metaType = derivedType.InheritanceRoot.GetInheritanceType(clrType); if (metaType is not null) { return metaType; } } } } /// /// This class defines the rules for inheritance behaviors. The rules: /// /// (1) The same field may not be mapped to different database columns. /// The DistinguishedMemberName and AreSameMember methods describe what 'same' means between two MemberInfos. /// (2) Discriminators held in fixed-length fields in the database don't need /// to be manually padded in inheritance mapping [InheritanceMapping(Code='x')]. /// /// static class InheritanceRules { /// /// Creates a name that is the same when the member should be considered 'same' /// for the purposes of the inheritance feature. /// internal static object DistinguishedMemberName(MemberInfo mi) { var pi = mi as PropertyInfo; var fi = mi as FieldInfo; if (fi is not null) { // Human readable variant: // return "fi:" + mi.Name + ":" + mi.DeclaringType; return new MetaPosition(mi); } else if (pi is not null) { var meth = default(MethodInfo); if (pi.CanRead) { meth = pi.GetGetMethod(); } if (meth is null && pi.CanWrite) { meth = pi.GetSetMethod(); } var isVirtual = meth is not null && meth.IsVirtual; // Human readable variant: // return "pi:" + mi.Name + ":" + (isVirtual ? "virtual" : mi.DeclaringType.ToString()); if (isVirtual) { return mi.Name; } else { return new MetaPosition(mi); } } else { throw Error.ArgumentOutOfRange(nameof(mi)); } } /// /// Compares two MemberInfos for 'same-ness'. /// internal static bool AreSameMember(MemberInfo mi1, MemberInfo mi2) => DistinguishedMemberName(mi1).Equals(DistinguishedMemberName(mi2)); } ================================================ FILE: src/DbExtensions/Metadata/Error.cs ================================================ // Copyright 2016-2022 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #region Based on code from .NET Framework #endregion using System; namespace DbExtensions.Metadata; static class Error { internal static Exception ArgumentOutOfRange(string paramName) { return new ArgumentOutOfRangeException(paramName); } internal static Exception InvalidFieldInfo(object p0, object p1, object p2) { return new ArgumentException($"Could not create FieldAccessor<{p0},{p1}> from FieldInfo '{p2}'."); } internal static Exception CouldNotCreateAccessorToProperty(object p0, object p1, object p2) { return new ArgumentException($"Could not create PropertyAccessor<{p0},{p1}> to {p2}."); } internal static Exception UnableToAssignValueToReadonlyProperty(object p0) { return new InvalidOperationException($"Unable to assign value to read only property '{p0}'."); } internal static Exception NoDiscriminatorFound(object p0) { return new InvalidOperationException($"The inheritance type '{p0}' does not declare a discriminator column."); } internal static Exception InheritanceTypeDoesNotDeriveFromRoot(object p0, object p1) { return new InvalidOperationException($"Inheritance type '{p0}' does not derive from inheritance root type '{p1}'."); } internal static Exception AbstractClassAssignInheritanceDiscriminator(object p0) { return new InvalidOperationException($"Abstract class '{p0}' should not be assigned an inheritance discriminator key."); } internal static Exception CannotGetInheritanceDefaultFromNonInheritanceClass() { return new InvalidOperationException("Mapping Problem: Cannot get inheritance default from class not mapped into an inheritance hierarchy."); } internal static Exception InheritanceCodeMayNotBeNull() { return new InvalidOperationException("Inheritance code value may not be null."); } internal static Exception InheritanceTypeHasMultipleDiscriminators(object p0) { return new InvalidOperationException($"The inherited type '{p0}' cannot have multiple discriminator key values."); } internal static Exception InheritanceCodeUsedForMultipleTypes(object p0) { return new InvalidOperationException($"The inheritance code '{p0}' is used for multiple types."); } internal static Exception InheritanceTypeHasMultipleDefaults(object p0) { return new InvalidOperationException($"The inheritance type '{p0}' has multiple defaults."); } internal static Exception InheritanceHierarchyDoesNotDefineDefault(object p0) { return new InvalidOperationException($"The inheritance hierarchy rooted at '{p0}' does not define a default."); } internal static Exception InheritanceSubTypeIsAlsoRoot(object p0) { return new InvalidOperationException($"The inheritance subtype '{p0}' is also declared as a root type."); } internal static Exception NonInheritanceClassHasDiscriminator(object p0) { return new InvalidOperationException($"The inheritance type '{p0}' has a discriminator but is not part of a mapped inheritance hierarchy."); } internal static Exception MemberMappedMoreThanOnce(object p0) { return new InvalidOperationException($"The member '{p0}' is mapped more than once."); } internal static Exception BadStorageProperty(object p0, object p1, object p2) { return new InvalidOperationException($"Bad Storage property: '{p0}' on member '{p1}.{p2}'."); } internal static Exception IncorrectAutoSyncSpecification(object p0) { return new InvalidOperationException($"Incorrect AutoSync specification for member '{p0}'."); } internal static Exception BadKeyMember(object p0, object p1, object p2) { return new InvalidOperationException($"Could not find key member '{p0}' of key '{p1}' on type '{p2}'. The key may be wrong or the field or property on '{p2}' has changed names."); } internal static Exception UnableToResolveRootForType(object p0) { return new InvalidOperationException($"Mapping Problem: Unable to resolve root for type '{p0}'."); } internal static Exception CouldNotFindTypeFromMapping(object p0) { return new InvalidOperationException($"Mapping Problem: Cannot find type '{p0}' from mapping."); } internal static Exception TwoMembersMarkedAsPrimaryKeyAndDBGenerated(object p0, object p1) { return new InvalidOperationException($"Members '{p0}' and '{p1}' both marked as IsPrimaryKey and IsDbGenerated."); } internal static Exception TwoMembersMarkedAsRowVersion(object p0, object p1) { return new InvalidOperationException($"Members '{p0}' and '{p1}' both marked as row version."); } internal static Exception TwoMembersMarkedAsInheritanceDiscriminator(object p0, object p1) { return new InvalidOperationException($"Members '{p0}' and '{p1}' both marked as inheritance discriminator."); } internal static Exception CouldNotFindRuntimeTypeForMapping(object p0) { return new InvalidOperationException($"Mapping Problem: Cannot find runtime type for type mapping '{p0}'."); } internal static Exception UnexpectedNull(object p0) { return new InvalidOperationException($"Unexpected null '{p0}'."); } internal static Exception InvalidDeleteOnNullSpecification(object p0) { return new InvalidOperationException($"Invalid DeleteOnNull specification for member '{p0}'. DeleteOnNull can only be true for singleton association members mapped to non-nullable foreign key columns."); } internal static Exception MappedMemberHadNoCorrespondingMemberInType(object p0, object p1) { return new NotSupportedException($"The column or association '{p0}' in the mapping had no corresponding member in type '{p1}'. Mapping members from above root type is not supported."); } internal static Exception DiscriminatorClrTypeNotSupported(object p0, object p1, object p2) { return new NotSupportedException($"Discriminator '{p0}.{p1}' may not be type '{p2}'."); } internal static Exception IdentityClrTypeNotSupported(object p0, object p1, object p2) { return new NotSupportedException($"Invalid type mapping for Identity member '{p0}.{p1}'. Type '{p2}' is not supported for identity members."); } internal static Exception PrimaryKeyInSubTypeNotSupported(object p0, object p1) { return new NotSupportedException($"The subtype '{p0}' cannot contain the primary key member '{p1}'."); } internal static Exception MismatchedThisKeyOtherKey(object p0, object p1) { return new InvalidOperationException($"The number of ThisKey columns is different from the number of OtherKey columns for the association property '{p0}' in the type '{p1}'."); } internal static Exception MappingOfInterfacesMemberIsNotSupported(object p0, object p1) { return new NotSupportedException($"The mapping of interface member {p0}.{p1} is not supported."); } internal static Exception UnmappedClassMember(object p0, object p1) { return new InvalidOperationException($"Class member {p0}.{p1} is unmapped."); } } ================================================ FILE: src/DbExtensions/Metadata/MappingSource.cs ================================================ // Copyright 2016-2022 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #region Based on code from .NET Framework #endregion using System; using System.Collections.Generic; using System.Threading; namespace DbExtensions.Metadata; /// /// Represents a source for mapping information. /// abstract class MappingSource { MetaModel _primaryModel; ReaderWriterLock _rwlock; Dictionary _secondaryModels; /// /// Gets the MetaModel representing a DataContext and all it's /// accessible tables, functions and entities. /// public MetaModel GetModel(Type dataContextType) { ArgumentNullException.ThrowIfNull(dataContextType); var model = default(MetaModel); if (_primaryModel is null) { model = CreateModel(dataContextType); Interlocked.CompareExchange(ref _primaryModel, model, null); } // if the primary one matches, use it! if (_primaryModel.ContextType == dataContextType) { return _primaryModel; } // the rest of this only happens if you are using the mapping source for // more than one context type // build a map if one is not already defined if (_secondaryModels is null) { Interlocked.CompareExchange(ref _secondaryModels, new Dictionary(), null); } // if we haven't created a read/writer lock, make one now if (_rwlock is null) { Interlocked.CompareExchange(ref _rwlock, new ReaderWriterLock(), null); } // lock the map and look inside MetaModel foundModel; _rwlock.AcquireReaderLock(Timeout.Infinite); try { if (_secondaryModels.TryGetValue(dataContextType, out foundModel)) { return foundModel; } } finally { _rwlock.ReleaseReaderLock(); } // if it wasn't found, lock for write and try again _rwlock.AcquireWriterLock(Timeout.Infinite); try { if (_secondaryModels.TryGetValue(dataContextType, out foundModel)) { return foundModel; } model ??= CreateModel(dataContextType); _secondaryModels.Add(dataContextType, model); } finally { _rwlock.ReleaseWriterLock(); } return model; } /// /// Creates a new instance of a MetaModel. This method is called by GetModel(). /// Override this method when defining a new type of MappingSource. /// /// /// protected abstract MetaModel CreateModel(Type dataContextType); } /// /// A mapping source that uses attributes on the context to create the mapping model. /// sealed class AttributeMappingSource : MappingSource { protected override MetaModel CreateModel(Type dataContextType) { ArgumentNullException.ThrowIfNull(dataContextType); return new AttributedMetaModel(this, dataContextType); } } ================================================ FILE: src/DbExtensions/Metadata/MappingSystem.cs ================================================ // Copyright 2016-2022 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #region Based on code from .NET Framework #endregion using System; namespace DbExtensions.Metadata; /// /// Shared rules governing the mapping system. /// static class MappingSystem { /// /// Return true if this is a clr type supported as an inheritance discriminator. /// /// /// internal static bool IsSupportedDiscriminatorType(Type type) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { type = type.GetGenericArguments()[0]; } switch (Type.GetTypeCode(type)) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.Char: case TypeCode.String: case TypeCode.Boolean: return true; } return false; } /// /// Return true if this is a CLR type supported as an identity member. Since identity /// management (caching) relies on key members being hashable, only types implementing /// GetHashCode are supported. Also, the runtime relies on identity members being comparable, /// so only types implementing Equals are supported. /// internal static bool IsSupportedIdentityType(Type type) { if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { type = type.GetGenericArguments()[0]; } if (type == typeof(Guid) || type == typeof(DateTime) || type == typeof(DateTimeOffset) || type == typeof(TimeSpan)) { return true; } switch (Type.GetTypeCode(type)) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.Char: case TypeCode.String: case TypeCode.Boolean: case TypeCode.Decimal: case TypeCode.Single: case TypeCode.Double: return true; } return false; } } ================================================ FILE: src/DbExtensions/Metadata/MetaModel.cs ================================================ // Copyright 2016-2022 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #region Based on code from .NET Framework #endregion using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Linq.Expressions; using System.Reflection; namespace DbExtensions.Metadata; /// /// A MetaModel is an abstraction representing the mapping between a database and domain objects /// abstract class MetaModel { /// /// The mapping source that originated this model. /// internal abstract MappingSource MappingSource { get; } /// /// The type of DataContext type this model describes. /// internal abstract Type ContextType { get; } /// /// The name of the database. /// internal abstract string DatabaseName { get; } /// /// Gets the MetaTable associated with a given type. /// /// The CLR row type. /// The MetaTable if one exists, otherwise null. public abstract MetaTable GetTable(Type rowType, MetaTableConfiguration config); /// /// Get an enumeration of all tables. /// /// An enumeration of all the MetaTables public abstract IEnumerable GetTables(); /// /// This method discovers the MetaType for the given Type. /// public abstract MetaType GetMetaType(Type type, MetaTableConfiguration config); } /// /// A MetaTable represents an abstraction of a database table (or view) /// abstract class MetaTable { /// /// The MetaModel containing this MetaTable. /// public abstract MetaModel Model { get; } /// /// The name of the table as defined by the database. /// public abstract string TableName { get; } /// /// The MetaType describing the type of the rows of the table. /// public abstract MetaType RowType { get; } } sealed class MetaTableConfiguration { public string DefaultComplexPropertySeparator { get; internal set; } public MetaTableConfiguration() { } internal MetaTableConfiguration(MetaTableConfiguration other) { this.DefaultComplexPropertySeparator = other.DefaultComplexPropertySeparator; } } /// /// A MetaType represents the mapping of a domain object type onto a database table's columns. /// abstract class MetaType { /// /// The MetaModel containing this MetaType. /// public abstract MetaModel Model { get; } /// /// The MetaTable using this MetaType for row definition. /// public abstract MetaTable Table { get; } /// /// The underlying CLR type. /// public abstract Type Type { get; } /// /// The name of the MetaType (same as the CLR type's name). /// public abstract string Name { get; } /// /// True if the MetaType is an entity type. /// public abstract bool IsEntity { get; } /// /// True if the underlying type can be instantiated as the result of a query. /// public abstract bool CanInstantiate { get; } /// /// The member that represents the auto-generated identity column, or null if there is none. /// public abstract MetaDataMember DBGeneratedIdentityMember { get; } /// /// The member that represents the row-version or timestamp column, or null if there is none. /// public abstract MetaDataMember VersionMember { get; } /// /// The member that represents the inheritance discriminator column, or null if there is none. /// internal abstract MetaDataMember Discriminator { get; } /// /// True if the type has any persistent member with an UpdateCheck policy other than Never. /// public abstract bool HasUpdateCheck { get; } /// /// True if the type is part of a mapped inheritance hierarchy. /// internal abstract bool HasInheritance { get; } /// /// True if this type defines an inheritance code. /// internal abstract bool HasInheritanceCode { get; } /// /// The inheritance code defined by this type. /// internal abstract object InheritanceCode { get; } /// /// True if this type is used as the default of an inheritance hierarchy. /// internal abstract bool IsInheritanceDefault { get; } /// /// The root type of the inheritance hierarchy. /// internal abstract MetaType InheritanceRoot { get; } /// /// The base metatype in the inheritance hierarchy. /// internal abstract MetaType InheritanceBase { get; } /// /// The type that is the default of the inheritance hierarchy. /// internal abstract MetaType InheritanceDefault { get; } /// /// Gets the MetaType for an inheritance sub type. /// /// The root or sub type of the inheritance hierarchy. /// The MetaType. internal abstract MetaType GetInheritanceType(Type type); /// /// Gets type associated with the specified inheritance code. /// /// The inheritance code /// The MetaType. internal abstract MetaType GetTypeForInheritanceCode(object code); /// /// Gets an enumeration of all types defined by an inheritance hierarchy. /// /// Enumeration of MetaTypes. internal abstract ReadOnlyCollection InheritanceTypes { get; } /// /// Gets an enumeration of the immediate derived types in an inheritance hierarchy. /// /// Enumeration of MetaTypes. internal abstract ReadOnlyCollection DerivedTypes { get; } /// /// Gets an enumeration of all the data members (fields and properties). /// public abstract ReadOnlyCollection DataMembers { get; } /// /// Gets an enumeration of all the persistent data members (fields and properties mapped into database columns). /// public abstract ReadOnlyCollection PersistentDataMembers { get; } /// /// Gets an enumeration of all the data members that define up the unique identity of the type. /// public abstract ReadOnlyCollection IdentityMembers { get; } /// /// Gets an enumeration of all the associations. /// public abstract ReadOnlyCollection Associations { get; } /// /// Gets the MetaDataMember associated with the specified member. /// /// The CLR member. /// The MetaDataMember if there is one, otherwise null. public abstract MetaDataMember GetDataMember(MemberInfo member); } /// /// A MetaDataMember represents the mapping between a domain object's field or property into a database table's column. /// abstract class MetaDataMember { /// /// The MetaType containing this data member. /// public abstract MetaType DeclaringType { get; } /// /// The underlying MemberInfo. /// public abstract MemberInfo Member { get; } /// /// The member that actually stores this member's data. /// public abstract MemberInfo StorageMember { get; } /// /// The name of the member, same as the MemberInfo name. /// public abstract string Name { get; } /// /// The name of the column (or constraint) in the database. /// public abstract string MappedName { get; } public virtual string QueryPath => Name; /// /// The oridinal position of this member in the default layout of query results. /// public abstract int Ordinal { get; } /// /// The type of this member. /// public abstract Type Type { get; } public abstract Type ConvertToType { get; } /// /// True if this member is declared by the specified type. /// /// Type to check. public abstract bool IsDeclaredBy(MetaType type); /// /// The accessor used to get/set the value of this member. /// public abstract MetaAccessor MemberAccessor { get; } /// /// The accessor used to get/set the storage value of this member. /// public abstract MetaAccessor StorageAccessor { get; } /// /// True if this member is mapped to a column (or constraint). /// public abstract bool IsPersistent { get; } /// /// True if this member defines an association relationship. /// public abstract bool IsAssociation { get; } /// /// True if this member is part of the type's identity. /// public abstract bool IsPrimaryKey { get; } /// /// True if this member is automatically generated by the database. /// public abstract bool IsDbGenerated { get; } /// /// True if this member represents the row version or timestamp. /// public abstract bool IsVersion { get; } /// /// True if this member represents the inheritance discriminator. /// internal abstract bool IsDiscriminator { get; } /// /// True if this member's value can be assigned the null value. /// public abstract bool CanBeNull { get; } /// /// The type of the database column. /// public abstract string DbType { get; } /// /// Expression defining a computed column. /// public abstract string Expression { get; } /// /// The optimistic concurrency check policy for this member. /// public abstract UpdateCheck UpdateCheck { get; } /// /// Specifies for inserts and updates when this member should be read back after the /// operation completes. /// public abstract AutoSync AutoSync { get; } /// /// The MetaAssociation corresponding to this member, or null if there is none. /// public abstract MetaAssociation Association { get; } public virtual object GetValueForDatabase(object instance) { var value = this.MemberAccessor.GetBoxedValue(instance); return ConvertValueForDatabase(value); } public object ConvertValueForDatabase(object value) { if (value is null || this.ConvertToType is null) { return value; } return Convert.ChangeType(value, this.ConvertToType, CultureInfo.InvariantCulture); } } /// /// A MetaAssociation represents an association relationship between two entity types. /// abstract class MetaAssociation { /// /// The type on the other end of the association. /// public abstract MetaType OtherType { get; } /// /// The member on this side that represents the association. /// public abstract MetaDataMember ThisMember { get; } /// /// The member on the other side of this association that represents the reverse association (may be null). /// public abstract MetaDataMember OtherMember { get; } /// /// A list of members representing the values on this side of the association. /// public abstract ReadOnlyCollection ThisKey { get; } /// /// A list of members representing the values on the other side of the association. /// public abstract ReadOnlyCollection OtherKey { get; } /// /// True if the association is OneToMany. /// public abstract bool IsMany { get; } /// /// True if the other type is the parent of this type. /// public abstract bool IsForeignKey { get; } /// /// True if the association is unique (defines a uniqueness constraint). /// public abstract bool IsUnique { get; } /// /// True if the association may be null (key values). /// public abstract bool IsNullable { get; } /// /// True if the ThisKey forms the identity (primary key) of the this type. /// public abstract bool ThisKeyIsPrimaryKey { get; } /// /// True if the OtherKey forms the identity (primary key) of the other type. /// public abstract bool OtherKeyIsPrimaryKey { get; } /// /// Specifies the behavior when the child is deleted (e.g. CASCADE, SET NULL). /// Returns null if no action is specified on delete. /// public abstract string DeleteRule { get; } /// /// Specifies whether the object should be deleted when this association /// is set to null. /// public abstract bool DeleteOnNull { get; } public void LoadCollection(object container, IEnumerable elements) { var accessor = (MetaCollectionAccessor)this.ThisMember.MemberAccessor; var collection = accessor.GetOrCreateBoxed(container); var setOtherMember = this.OtherMember is { Association.IsMany: false }; foreach (var element in elements) { if (setOtherMember) { var elementObj = element; this.OtherMember.MemberAccessor.SetBoxedValue(ref elementObj, container); } accessor.AddBoxedElement(ref collection, element); } } } /// /// A MetaAccessor /// abstract class MetaAccessor { /// /// The type of the member accessed by this accessor. /// public abstract Type Type { get; } /// /// Gets the value as an object. /// /// The instance to get the value from. /// Value. public abstract object GetBoxedValue(object instance); /// /// Sets the value as an object. /// /// The instance to set the value into. /// The value to set. public abstract void SetBoxedValue(ref object instance, object value); /// /// True if the instance has a loaded or assigned value. /// internal virtual bool HasValue(object instance) => true; /// /// True if the instance has an assigned value. /// internal virtual bool HasAssignedValue(object instance) => true; /// /// True if the instance has a value loaded from a deferred source. /// internal virtual bool HasLoadedValue(object instance) => false; } /// /// A strongly-typed MetaAccessor. Used for reading from and writing to /// CLR objects. /// /// The type of the object /// The type of the accessed member abstract class MetaAccessor : MetaAccessor { /// /// The underlying CLR type. /// public override Type Type => typeof(TMember); /// /// Set the boxed value on an instance. /// public override void SetBoxedValue(ref object instance, object value) { var tInst = (TEntity)instance; SetValue(ref tInst, (TMember)value); instance = tInst; } /// /// Retrieve the boxed value. /// public override object GetBoxedValue(object instance) => GetValue((TEntity)instance); /// /// Gets the strongly-typed value. /// public abstract TMember GetValue(TEntity instance); /// /// Sets the strongly-typed value /// public abstract void SetValue(ref TEntity instance, TMember value); } abstract class MetaCollectionAccessor : MetaAccessor { public abstract Type ElementType { get; } public abstract void AddBoxedElement(ref object collection, object element); public abstract object GetOrCreateBoxed(object instance); } sealed class MetaCollectionAccessor : MetaCollectionAccessor { readonly MetaAccessor _propAccessor; readonly Action _addFn; readonly Func _factory; public override Type Type => _propAccessor.Type; public override Type ElementType => typeof(TElement); internal MetaCollectionAccessor( MetaAccessor propAccessor, Action addFn) { _propAccessor = propAccessor; _addFn = addFn; _factory = CreateFactory(); } static Func CreateFactory() { var newExpr = Expression.New(typeof(TCollection)); var lambdaExpr = Expression.Lambda>(newExpr); return lambdaExpr.Compile(); } public override object GetOrCreateBoxed(object instance) { var container = (TContainer)instance; var collection = GetValue(container); if (collection is null) { collection = _factory.Invoke(); SetValue(ref container, collection); } return collection; } public TCollection GetValue(TContainer instance) => _propAccessor.GetValue(instance); public void SetValue(ref TContainer instance, TCollection value) => _propAccessor.SetValue(ref instance, value); public void AddElement(ref TCollection collection, TElement element) => _addFn.Invoke(collection, element); public override void SetBoxedValue(ref object instance, object value) => _propAccessor.SetBoxedValue(ref instance, value); public override object GetBoxedValue(object instance) => _propAccessor.GetBoxedValue(instance); public override void AddBoxedElement(ref object collection, object element) { var TCol = (TCollection)collection; AddElement(ref TCol, (TElement)element); collection = TCol!; } } ================================================ FILE: src/DbExtensions/Metadata/TypeSystem.cs ================================================ // Copyright 2016-2022 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #region Based on code from .NET Framework #endregion using System; using System.Collections; using System.Collections.Generic; using System.Reflection; namespace DbExtensions.Metadata; static class TypeSystem { internal static bool IsSequenceType(Type seqType) { return seqType != typeof(string) && seqType != typeof(byte[]) && seqType != typeof(char[]) && FindIEnumerable(seqType) is not null; } static Type FindIEnumerable(Type seqType) { if (seqType is null || seqType == typeof(string)) { return null; } if (seqType.IsArray) { return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType()); } if (seqType.IsGenericType) { foreach (var arg in seqType.GetGenericArguments()) { var ienum = typeof(IEnumerable<>).MakeGenericType(arg); if (ienum.IsAssignableFrom(seqType)) { return ienum; } } } var ifaces = seqType.GetInterfaces(); if (ifaces is not null && ifaces.Length > 0) { foreach (var iface in ifaces) { var ienum = FindIEnumerable(iface); if (ienum is not null) { return ienum; } } } if (seqType.BaseType is not null && seqType.BaseType != typeof(object)) { return FindIEnumerable(seqType.BaseType); } return null; } internal static Type GetElementType(Type seqType) { var ienum = FindIEnumerable(seqType); if (ienum is null) { return seqType; } return ienum.GetGenericArguments()[0]; } internal static bool IsNullableType(Type type) { return type is not null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); } internal static Type GetMemberType(MemberInfo mi) { if (mi is FieldInfo fi) { return fi.FieldType; } if (mi is PropertyInfo pi) { return pi.PropertyType; } if (mi is EventInfo ei) { return ei.EventHandlerType; } return null; } internal static IEnumerable GetAllFields(Type type, BindingFlags flags) { var seen = new Dictionary(); var currentType = type; do { foreach (var fi in currentType.GetFields(flags)) { if (fi.IsPrivate || type == currentType) { var mp = new MetaPosition(fi); seen[mp] = fi; } } currentType = currentType.BaseType; } while (currentType is not null); return seen.Values; } internal static IEnumerable GetAllProperties(Type type, BindingFlags flags) { var seen = new Dictionary(); var currentType = type; do { foreach (var pi in currentType.GetProperties(flags)) { if (type == currentType || IsPrivate(pi)) { var mp = new MetaPosition(pi); seen[mp] = pi; } } currentType = currentType.BaseType; } while (currentType is not null); return seen.Values; } static bool IsPrivate(PropertyInfo pi) { var mi = pi.GetGetMethod() ?? pi.GetSetMethod(); if (mi is not null) { return mi.IsPrivate; } return true; } } /// /// Hashable MetaDataToken+Assembly. This type uniquely describes a metadata element /// like a MemberInfo. MetaDataToken by itself is not sufficient because its only /// unique within a single assembly. /// struct MetaPosition : IEqualityComparer, IEqualityComparer { readonly int _metadataToken; readonly Assembly _assembly; internal MetaPosition(MemberInfo mi) : this(mi.DeclaringType.Assembly, mi.MetadataToken) { } private MetaPosition(Assembly assembly, int metadataToken) { _assembly = assembly; _metadataToken = metadataToken; } // Equality is implemented here according to the advice in // CLR via C# 2ed, J. Richter, p 146. In particular, ValueType.Equals // should not be called for perf reasons. public override bool Equals(object obj) { if (obj is null) { return false; } if (obj.GetType() != GetType()) { return false; } return AreEqual(this, (MetaPosition)obj); } public override int GetHashCode() => _metadataToken; public bool Equals(MetaPosition x, MetaPosition y) => AreEqual(x, y); public int GetHashCode(MetaPosition obj) => obj._metadataToken; bool IEqualityComparer.Equals(object x, object y) => Equals((MetaPosition)x, (MetaPosition)y); int IEqualityComparer.GetHashCode(object obj) => GetHashCode((MetaPosition)obj); static bool AreEqual(MetaPosition x, MetaPosition y) { return (x._metadataToken == y._metadataToken) && (x._assembly == y._assembly); } // Since MetaPositions are immutable, we overload the equality operator // to test for value equality, rather than reference equality public static bool operator ==(MetaPosition x, MetaPosition y) => AreEqual(x, y); public static bool operator !=(MetaPosition x, MetaPosition y) => !AreEqual(x, y); } ================================================ FILE: src/DbExtensions/PocoMapper.cs ================================================ // Copyright 2010-2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Data.Common; using System.Diagnostics; using System.Globalization; using System.Linq.Expressions; using System.Reflection; using System.Runtime.InteropServices; using System.Text; namespace DbExtensions; #nullable enable partial class Database { /// /// Maps the results of the to objects. /// The query is deferred-executed. /// /// The type of objects to map the results to. /// The query. /// The results of the query as objects. public IEnumerable Map(SqlBuilder query) { ArgumentNullException.ThrowIfNull(query); var mapper = CreatePocoMapper(typeof(TResult)); return Map(query, r => (TResult)mapper.PocoMap(r)); } /// public IAsyncEnumerable AsyncMap(SqlBuilder query) { ArgumentNullException.ThrowIfNull(query); var mapper = CreatePocoMapper(typeof(TResult)); return AsyncMap(query, r => (TResult)mapper.PocoMap(r)); } /// /// Maps the results of the to objects of type /// specified by the parameter. /// The query is deferred-executed. /// /// The query. /// The type of objects to map the results to. /// The results of the query as objects of type specified by the parameter. public IEnumerable Map(SqlBuilder query, Type resultType) { ArgumentNullException.ThrowIfNull(query); ArgumentNullException.ThrowIfNull(resultType); var mapper = CreatePocoMapper(resultType); return Map(query, mapper.PocoMap); } /// public IAsyncEnumerable AsyncMap(SqlBuilder query, Type resultType) { ArgumentNullException.ThrowIfNull(query); ArgumentNullException.ThrowIfNull(resultType); var mapper = CreatePocoMapper(resultType); return AsyncMap(query, mapper.PocoMap); } internal PocoMapper CreatePocoMapper(Type type) { return new PocoMapper(type) { Log = this.Configuration.Log, }; } } partial class SqlSet { Dictionary>? _manyIncludes; partial void Initialize2(SqlSet set) { if (set._manyIncludes is { } incl) { _manyIncludes = new(incl); } Initialize3(set); } partial void Initialize3(SqlSet set); private protected void AddManyInclude(string[] path, Action loader) { _manyIncludes ??= new(); _manyIncludes.Add(path, loader); } partial void PocoMap(bool singleResult, SqlBuilder query, ref IEnumerable? results) { var mapper = CreatePocoMapper(singleResult); results = _db.Map(query, mapper.PocoMap); } partial void PocoAsyncMap(bool singleResult, SqlBuilder query, ref IAsyncEnumerable? results) { var mapper = CreatePocoMapper(singleResult); results = _db.AsyncMap(query, mapper.PocoMap); } private protected PocoMapper CreatePocoMapper(bool singleResult) { Debug.Assert(_resultType is not null); var mapper = _db.CreatePocoMapper(_resultType); mapper.SingleResult = singleResult; mapper.ManyIncludes = _manyIncludes; return mapper; } } partial class SqlSet { /// This method is used by auto-generated Include methods. /// [EditorBrowsable(EditorBrowsableState.Never)] public SqlSet WithManyInclude(string[] path, Action loader) { var clone = (SqlSet)Clone(); clone.AddManyInclude(path, loader); return clone; } partial void PocoMap(bool singleResult, SqlBuilder query, ref IEnumerable? results) { var mapper = CreatePocoMapper(singleResult); results = _db.Map(query, r => (TResult)mapper.PocoMap(r)); } partial void PocoAsyncMap(bool singleResult, SqlBuilder query, ref IAsyncEnumerable? results) { var mapper = CreatePocoMapper(singleResult); results = _db.AsyncMap(query, r => (TResult)mapper.PocoMap(r)); } } partial class Mapper { partial void InitializeMappingContext2(MappingContext context) { if (this is PocoMapper pocoMapper) { context.ManyLoaders = pocoMapper.GetManyLoaders(); } InitializeMappingContext3(context); } partial void InitializeMappingContext3(MappingContext context); } sealed class PocoMapper : Mapper { static readonly ConcurrentDictionary> _compiledMapCache = new(); static readonly ConcurrentDictionary> _compiledLoadCache = new(); readonly Type _type; Func? _compiledMapFn; Action? _compiledLoadFn; public Dictionary>? ManyIncludes { get; set; } protected override bool CanUseConstructorMapping => true; public PocoMapper(Type type) { _type = type; } public object PocoMap(DbDataReader record) { if (_compiledMapFn is null) { var arg = new CacheArg(this, record); static Func fnFactory(CacheKey k, CacheArg arg) => ((PocoNode)arg.Mapper.GetRootNode(arg.Record)).CompileMap(); _compiledMapFn = (record.FieldCount > 0) ? _compiledMapCache.GetOrAdd(BuildCacheKey(_type, record), fnFactory, arg) : fnFactory(default, arg); } var instance = _compiledMapFn.Invoke(record, this.MappingContext); return instance; } public void PocoLoad(object instance, DbDataReader record) { if (_compiledLoadFn is null) { var arg = new CacheArg(this, record); static Action fnFactory(CacheKey k, CacheArg arg) => ((PocoNode)arg.Mapper.GetRootNode(arg.Record)).CompileLoad(); _compiledLoadFn = (record.FieldCount > 0) ? _compiledLoadCache.GetOrAdd(BuildCacheKey(_type, record), fnFactory, arg) : fnFactory(default, arg); } _compiledLoadFn.Invoke(record, this.MappingContext, instance); } static CacheKey BuildCacheKey(Type type, DbDataReader record) { var fieldCount = record.FieldCount; string names; if (fieldCount == 0) { names = String.Empty; } else if (fieldCount == 1) { names = record.GetName(0); } else { var sb = new StringBuilder(); for (var i = 0; i < fieldCount; i++) { if (i > 0) { sb.Append('\n'); } sb.Append(record.GetName(i)); } names = sb.ToString(); } return new CacheKey(type, names); } internal Dictionary>>? GetManyLoaders() { if (this.ManyIncludes is null or { Count: 0 }) { return null; } var collectionNodes = new Dictionary>>(); foreach (var pair in this.ManyIncludes) { var path = pair.Key; var containerHash = (path.Length == 1) ? PocoNode.RootNodeHash : String.Join('.', path, 0, path.Length - 1).GetHashCode(); ref var containerCols = ref CollectionsMarshal.GetValueRefOrAddDefault(collectionNodes, containerHash, out var exists); if (!exists) { containerCols = new(); } containerCols!.Add(pair.Value); } return collectionNodes; } protected override Node CreateRootNode() => new PocoNode(_type, default, isComplex: true); protected override Node? CreateSimpleProperty(Node container, string propertyName, int columnOrdinal) { var pocoContainer = (PocoNode)container; var property = GetProperty(pocoContainer.UnderlyingType, propertyName); if (property is null) { return null; } return new PocoNode(property, pocoContainer, columnOrdinal); } protected override Node? CreateComplexProperty(Node container, string propertyName) { var pocoContainer = (PocoNode)container; var property = GetProperty(pocoContainer.UnderlyingType, propertyName); if (property is null) { return null; } return new PocoNode(property, pocoContainer, isComplex: true); } protected override Node CreateParameterNode(int columnOrdinal, ParameterInfo paramInfo) => new PocoNode(paramInfo, columnOrdinal); protected override Node CreateParameterNode(ParameterInfo paramInfo) => new PocoNode(paramInfo, isComplex: true); static PropertyInfo? GetProperty(Type declaringType, string propertyName) { var property = declaringType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property is null) { return property; } if (!property.CanWrite) { throw new InvalidOperationException($"'{property.ReflectedType!.FullName}' property '{property.Name}' doesn't have a setter."); } return property; } readonly record struct CacheKey(Type Type, string Names); readonly record struct CacheArg(PocoMapper Mapper, DbDataReader Record); } partial class MappingContext { public Dictionary>>? ManyLoaders; public void LoadMany(int nodeHash, object instance, DbDataReader record) { if (this.ManyLoaders?.TryGetValue(nodeHash, out var colLoaders) == true && colLoaders.Count > 0) { if (this.SingleResult) { // if the query is expected to return a single result at most // we close the data reader to allow for collections to be loaded // using the same connection (for providers that do not support MARS) record.Close(); } foreach (var loader in colLoaders) { loader.Invoke(instance); } } } } sealed partial class PocoNode : Node { int? _propertyHash; internal const int RootNodeHash = 0; private PocoNode? Container { get; } private Type Type { get; } public Type UnderlyingType { get; } public override int ColumnOrdinal { get; } public override string TypeName => UnderlyingType.FullName!; public override bool IsComplex { get; } private PropertyInfo? Property { get; } public override string? PropertyName => Property?.Name; public int PropertyHash => _propertyHash ??= (Property is null ? RootNodeHash : GetPropertyPath().GetHashCode()); public ParameterInfo? Parameter { get; } public bool CanBeNull { get; } internal PocoNode(Type type, int columnOrdinal, bool isComplex) { var underlyingNvt = Nullable.GetUnderlyingType(type); this.Type = type; this.UnderlyingType = underlyingNvt ?? type; this.ColumnOrdinal = columnOrdinal; this.IsComplex = isComplex; this.CanBeNull = !type.IsValueType || underlyingNvt is not null; } internal PocoNode(PropertyInfo property, PocoNode container, int columnOrdinal = default, bool isComplex = default) : this(property.PropertyType, columnOrdinal, isComplex) { this.Container = container; this.Property = property; } internal PocoNode(ParameterInfo parameter, int columnOrdinal = default, bool isComplex = default) : this(parameter.ParameterType, columnOrdinal, isComplex) { this.Parameter = parameter; } public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) => this.UnderlyingType.GetConstructors(bindingAttr); string GetPropertyPath() { if (this.Property is null) { return String.Empty; } var path = this.PropertyName!; var container = this.Container; while (container is { PropertyName: { } containerName }) { path = containerName + "." + path; container = container.Container; } return path; } bool IsInParameter() => this.Parameter is not null || this.Container?.IsInParameter() == true; public override string ToString() { if (this.Parameter != null) { return this.Parameter.ToString(); } if (this.Property != null) { return this.Property.DeclaringType!.ToString() + ":" + this.PropertyName!.ToString(); } return this.Type.Name; } internal Func CompileMap() { var recordParam = Expression.Parameter(typeof(DbDataReader)); var contextParam = Expression.Parameter(typeof(MappingContext)); var statements = new List(); var varExpr = GenerateExpressionComplex(statements, recordParam, contextParam); statements.Add(Expression.Convert(varExpr, typeof(object))); var lambda = Expression.Lambda>( Expression.Block([varExpr], statements), recordParam, contextParam); return lambda.Compile(); } internal Action CompileLoad() { var recordParam = Expression.Parameter(typeof(DbDataReader)); var contextParam = Expression.Parameter(typeof(MappingContext)); var instanceParam = Expression.Parameter(typeof(object)); var varExpr = Expression.Variable(this.Type); var statements = new List { Expression.Assign(varExpr, Expression.Convert(instanceParam, varExpr.Type)) }; GenerateLoad(varExpr, statements, recordParam, contextParam); var lambda = Expression.Lambda>( Expression.Block([varExpr], statements), recordParam, contextParam, instanceParam); return lambda.Compile(); } ParameterExpression GenerateExpressionNullable(List statements, ParameterExpression recordParam, ParameterExpression contextParam) { var varExpr = Expression.Variable(this.Type); if (!this.CanBeNull) { var buffer = new List(); var exprVarExpr = GenerateExpression(buffer, recordParam, contextParam); if (buffer is [BinaryExpression binExpr and { NodeType: ExpressionType.Assign }] && binExpr.Left == exprVarExpr) { statements.Add(Expression.Assign(varExpr, binExpr.Right)); } else { buffer.Add(Expression.Assign(varExpr, exprVarExpr)); statements.Add(Expression.Block( [exprVarExpr], buffer)); } } else { var isDbNulls = new List(); foreach (var ordinal in GetAllOrdinals()) { isDbNulls.Add(Expression.Call( recordParam, References.IsDbNullMethod, Expression.Constant(ordinal, typeof(int)))); } var allNullsExpr = isDbNulls[0]; for (var i = 1; i < isDbNulls.Count; i++) { allNullsExpr = Expression.MakeBinary(ExpressionType.AndAlso, allNullsExpr, isDbNulls[i]); } var falseBuffer = new List(); var exprVarExpr = GenerateExpression(falseBuffer, recordParam, contextParam); var valueExpr = (Expression)exprVarExpr; var simpleExpr = false; if (falseBuffer is [BinaryExpression binExpr and { NodeType: ExpressionType.Assign }] && binExpr.Left == exprVarExpr) { valueExpr = binExpr.Right; simpleExpr = true; } if (this.UnderlyingType.IsValueType) { valueExpr = Expression.Convert(valueExpr, this.Type); } var nullExpr = Expression.Constant(null, varExpr.Type); if (simpleExpr) { statements.Add(Expression.Assign( varExpr, Expression.Condition( allNullsExpr, nullExpr, valueExpr))); } else { falseBuffer.Add(Expression.Assign(varExpr, valueExpr)); statements.Add( Expression.IfThenElse( allNullsExpr, Expression.Assign(varExpr, nullExpr), Expression.Block( [exprVarExpr], falseBuffer))); } } return varExpr; } ParameterExpression GenerateExpression(List statements, ParameterExpression recordParam, ParameterExpression contextParam) { var varExpr = (this.IsComplex) ? GenerateExpressionComplex(statements, recordParam, contextParam) : GenerateExpressionSimple(statements, recordParam); return varExpr; } ParameterExpression GenerateExpressionComplex(List statements, ParameterExpression recordParam, ParameterExpression contextParam) { var varExpr = Expression.Variable(this.UnderlyingType); if (this.HasConstructorParameters) { var vars = new ParameterExpression[this.ConstructorParameters.Count]; var buffer = new List(); var i = -1; foreach (var pair in this.ConstructorParameters) { i++; var paramNode = (PocoNode)pair.Value; vars[i] = paramNode.GenerateExpressionNullable(buffer, recordParam, contextParam); } var newExpr = Expression.New(this.Constructor!, vars); buffer.Add(Expression.Assign(varExpr, newExpr)); statements.Add(Expression.Block(vars, buffer)); } else { var newExpr = Expression.New(this.UnderlyingType); statements.Add(Expression.Assign(varExpr, newExpr)); } if (this.HasProperties) { GenerateLoad(varExpr, statements, recordParam, contextParam); } return varExpr; } void GenerateLoad(ParameterExpression targetExpr, List statements, ParameterExpression recordParam, ParameterExpression contextParam) { var nullExpr = Expression.Constant(null); for (var i = 0; i < this.Properties.Count; i++) { var prop = (PocoNode)this.Properties[i]; var memberExpr = Expression.Property(targetExpr, prop.Property!); if (!prop.IsComplex || prop.HasConstructorParameters) { var buffer = new List(); var exprVarExpr = prop.GenerateExpressionNullable(buffer, recordParam, contextParam); if (buffer is [BinaryExpression binExpr and { NodeType: ExpressionType.Assign }] && binExpr.Left == exprVarExpr) { statements.Add(Expression.Assign(memberExpr, binExpr.Right)); } else { buffer.Add(Expression.Assign(memberExpr, exprVarExpr)); statements.Add(Expression.Block( [exprVarExpr], buffer)); } } else { var buffer = new Expression[2]; var varExpr = Expression.Variable(prop.Type); buffer[0] = Expression.Assign(varExpr, memberExpr); var trueBuffer = new List(); prop.GenerateLoad(varExpr, trueBuffer, recordParam, contextParam); var falseBuffer = new List(); var newVarExpr = prop.GenerateExpressionNullable(falseBuffer, recordParam, contextParam); falseBuffer.Add(Expression.Assign(memberExpr, newVarExpr)); buffer[1] = Expression.IfThenElse( Expression.MakeBinary(ExpressionType.NotEqual, varExpr, nullExpr), (trueBuffer.Count == 1) ? trueBuffer[0] : Expression.Block(trueBuffer), Expression.Block( [newVarExpr], falseBuffer)); statements.Add(Expression.Block( [varExpr], buffer)); } } if (!IsInParameter()) { statements.Add(Expression.Call( contextParam, References.LoadManyMethod, Expression.Constant(this.PropertyHash), targetExpr, recordParam)); } } ParameterExpression GenerateExpressionSimple(List statements, ParameterExpression recordParam) { var varExpr = Expression.Variable(this.UnderlyingType); var ordinalExpr = Expression.Constant(this.ColumnOrdinal); var convertToType = default(Type); GetConvertToType(ref convertToType); var columnType = convertToType ?? this.UnderlyingType; var typeCode = Type.GetTypeCode(columnType); var isEnum = this.UnderlyingType.IsEnum; Expression valueExpr; if (References.RecordGetMethods.TryGetValue(typeCode, out var recordMethod) && (typeCode is not TypeCode.Object || this.Type == typeof(object))) { valueExpr = Expression.Call(recordParam, recordMethod, ordinalExpr); } else { valueExpr = Expression.Call( recordParam, References.GetFieldValueOpenMethod.MakeGenericMethod(columnType), ordinalExpr); } var targetType = this.UnderlyingType; var targetTypeExpr = Expression.Constant(targetType, typeof(Type)); if (convertToType != null) { if (convertToType == typeof(string) && isEnum) { valueExpr = Expression.Call( References.EnumParseOpenMethod.MakeGenericMethod(targetType), valueExpr); } else { valueExpr = Expression.Call( References.ConvertChangeTypeMethod, varExpr, targetTypeExpr, Expression.Property(null, References.InvariantCultureProperty)); } } else if (isEnum) { var trueExpr = (Expression)Expression.Call( References.EnumParseOpenMethod.MakeGenericMethod(targetType), Expression.Call(recordParam, References.RecordGetMethods[TypeCode.String], ordinalExpr)); var falseExpr = valueExpr; falseExpr = Expression.Convert(falseExpr, targetType); valueExpr = Expression.Condition( Expression.MakeBinary( ExpressionType.Equal, Expression.Call(recordParam, References.GetFieldTypeMethod, ordinalExpr), Expression.Constant(typeof(string), typeof(Type))), trueExpr, falseExpr); } if (valueExpr.Type != varExpr.Type) { valueExpr = Expression.Convert(valueExpr, varExpr.Type); } statements.Add(Expression.Assign(varExpr, valueExpr)); return varExpr; } IEnumerable GetAllOrdinals() { if (this.IsComplex) { if (this.HasConstructorParameters) { foreach (var pair in this.ConstructorParameters) { foreach (var o in ((PocoNode)pair.Value).GetAllOrdinals()) { yield return o; } } } if (this.HasProperties) { #pragma warning disable IDE0220 foreach (PocoNode prop in this.Properties) { #pragma warning restore IDE0220 foreach (var o in prop.GetAllOrdinals()) { yield return o; } } } yield break; } yield return this.ColumnOrdinal; } partial void GetConvertToType(ref Type? convertToType); static partial class References { public static readonly MethodInfo ConvertChangeTypeMethod = typeof(Convert) .GetMethod(nameof(Convert.ChangeType), BindingFlags.Public | BindingFlags.Static, null, [typeof(object), typeof(Type), typeof(IFormatProvider)], null)!; public static readonly MethodInfo EnumParseOpenMethod = typeof(Enum) .GetMethod(nameof(Enum.Parse), 1, BindingFlags.Public | BindingFlags.Static, null, [typeof(string)], null)!; public static readonly MethodInfo GetFieldTypeMethod = typeof(DbDataReader) .GetMethod(nameof(DbDataReader.GetFieldType))!; public static readonly MethodInfo GetFieldValueOpenMethod = typeof(DbDataReader) .GetMethod(nameof(DbDataReader.GetFieldValue))!; public static readonly PropertyInfo InvariantCultureProperty = typeof(CultureInfo) .GetProperty(nameof(CultureInfo.InvariantCulture))!; public static readonly MethodInfo IsDbNullMethod = typeof(DbDataReader) .GetMethod(nameof(DbDataReader.IsDBNull))!; public static readonly MethodInfo LoadManyMethod = typeof(MappingContext) .GetMethod(nameof(MappingContext.LoadMany))!; public static readonly Dictionary RecordGetMethods = new() { { TypeCode.Boolean, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetBoolean))! }, { TypeCode.Byte, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetByte))! }, { TypeCode.Char, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetChar))! }, { TypeCode.DateTime, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetDateTime))! }, { TypeCode.Decimal, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetDecimal))! }, { TypeCode.Double, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetDouble))! }, { TypeCode.Int16, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetInt16))! }, { TypeCode.Int32, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetInt32))! }, { TypeCode.Int64, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetInt64))! }, { TypeCode.Object, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetValue))! }, { TypeCode.Single, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetFloat))! }, { TypeCode.String, typeof(DbDataReader).GetMethod(nameof(DbDataReader.GetString))! }, }; } } ================================================ FILE: src/DbExtensions/Properties/AssemblyInfo.cs ================================================ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] [assembly: InternalsVisibleTo("DbExtensions.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] ================================================ FILE: src/DbExtensions/SqlBuilder.cs ================================================ // Copyright 2009-2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using System.Text; namespace DbExtensions; using InterpolatedString = InterpolatedStringHandlerArgumentAttribute; #nullable enable interface ISqlFragment { IList ParameterValues { get; } string ToString(); } /// /// Represents a mutable SQL string. /// /// For information on how to use SqlBuilder see SqlBuilder Tutorial. [CLSCompliant(true)] [DebuggerDisplay($"{{{nameof(Buffer)}}}")] [InterpolatedStringHandler] public sealed partial class SqlBuilder : ISqlFragment { const int _defaultCapacity = 48; SqlClause? _nextClause; bool? _ifCondition; bool? _appendIfCondition; /// /// The underlying . /// public StringBuilder Buffer { get; } /// /// The parameter objects to be included in the database command. /// public Collection ParameterValues { get; } IList ISqlFragment.ParameterValues => ParameterValues; /// /// Gets or sets the current SQL clause, used to identify consecutive /// appends to the same clause. /// public SqlClause? CurrentClause { get; set; } /// /// Gets or sets the next SQL clause. Used by clause continuation methods, /// such as and . /// public SqlClause? NextClause { get => _nextClause; set { _nextClause = value; _ifCondition = null; _appendIfCondition = null; } } /// /// Returns true if the buffer is empty. /// public bool IsEmpty => Buffer.Length == 0; internal bool ElseOK => _ifCondition == false; internal bool AppendElseOK => _appendIfCondition == false; /// /// Concatenates a specified separator between each element of a /// specified array, yielding a single concatenated . /// /// The string to use as a separator. /// An array of . /// /// A consisting of the elements of /// interspersed with the string. /// public static SqlBuilder JoinSql(string? separator, params SqlBuilder?[] values) { ArgumentNullException.ThrowIfNull(values); var sql = new SqlBuilder(); if (values.Length == 0) { return sql; } separator ??= String.Empty; var first = values[0]; if (first is not null) { sql.AppendSql(first); } for (int i = 1; i < values.Length; i++) { sql.Append(separator); var val = values[i]; if (val is not null) { sql.AppendSql(val); } } return sql; } /// /// Concatenates the members of a constructed collection of type , /// using the specified between each member. /// /// The string to use as a separator. /// A collection that contains the objects to concatenate. /// /// A that consists of the members of delimited /// by the string. If has no members, the method returns /// an empty . /// public static SqlBuilder JoinSql(string? separator, IEnumerable values) { ArgumentNullException.ThrowIfNull(values); var sql = new SqlBuilder(); separator ??= String.Empty; using (var enumerator = values.GetEnumerator()) { if (!enumerator.MoveNext()) { return sql; } if (enumerator.Current is not null) { sql.AppendSql(enumerator.Current); } while (enumerator.MoveNext()) { sql.Append(separator); if (enumerator.Current is not null) { sql.AppendSql(enumerator.Current); } } } return sql; } /// /// Initializes a new instance of the class. /// public SqlBuilder() { this.Buffer = new(_defaultCapacity); this.ParameterValues = new(); } private SqlBuilder(SqlBuilder other) { ArgumentNullException.ThrowIfNull(other); // When you clone a builder you most likely want to modify the clone, // therefore use default capacity as min. this.Buffer = new(Math.Max(_defaultCapacity, other.Buffer.Capacity)); this.Buffer.Append(other.Buffer); this.ParameterValues = new(new List(other.ParameterValues)); this.CurrentClause = other.CurrentClause; _nextClause = other._nextClause; _ifCondition = other._ifCondition; _appendIfCondition = other._appendIfCondition; } /// [EditorBrowsable(EditorBrowsableState.Never)] public SqlBuilder(int literalLength, int formattedCount) { // This constructor is used by interpolated strings. // Capacities are optimized for "static" queries. var queryLength = literalLength + PlaceholderLengthSum(formattedCount); this.Buffer = new(queryLength); this.ParameterValues = new(new List(formattedCount)); } static int PlaceholderLengthSum(int formattedCount) { var result = 0; for (var i = 0; i < formattedCount; i++) { result += i switch { < 10 => 1, < 100 => 2, < 1_000 => 3, < 10_000 => 4, < 100_000 => 5, < 1_000_000 => 6, < 10_000_000 => 7, < 100_000_000 => 8, < 1_000_000_000 => 9, _ => 10 } + 2; } return result; } /// [EditorBrowsable(EditorBrowsableState.Never)] public void AppendLiteral(string value) => this.Buffer.Append(value); /// [EditorBrowsable(EditorBrowsableState.Never)] public void AppendFormatted(object? value, int alignment = 0, string? format = null) => AppendPlaceholder(value, format); /// /// Appends the SQL clause identified by . /// /// The type of the SQL clause. /// A reference to this instance after the append operation has completed. public SqlBuilder AppendClause() where TClause : SqlClause, new() => AppendClause(SqlClause.Instance()); /// /// Appends the SQL . /// /// The clause to append. /// A reference to this instance after the append operation has completed. public SqlBuilder AppendClause(SqlClause clause) { ArgumentNullException.ThrowIfNull(clause); if (clause is SqlClause.Current) { clause = this.NextClause ?? this.CurrentClause ?? throw new InvalidOperationException(); } if (clause.Separator is null || !String.Equals(clause.Name, this.CurrentClause?.Name, StringComparison.OrdinalIgnoreCase)) { if (!this.IsEmpty) { this.Buffer.AppendLine(); } if (clause.Name is { } name) { this.Buffer.Append(name) .Append(' '); } } else if (clause.Separator is { } sep) { this.Buffer.Append(sep); } this.CurrentClause = clause; this.NextClause = null; return this; } /// /// Appends to this instance. /// /// A . /// A reference to this instance after the append operation has completed. public SqlBuilder AppendSql(SqlBuilder sql) { ArgumentNullException.ThrowIfNull(sql); AppendFragment(sql, this.Buffer); return this; } internal SqlBuilder AppendFragment(ISqlFragment sql) { AppendFragment(sql, this.Buffer); return this; } void AppendFragment(ISqlFragment sql, StringBuilder sb) { if (sql.ParameterValues.Count == 0) { if (sql is SqlBuilder sqlB) { sb.Append(sqlB.Buffer); } else { sb.Append(sql.ToString()); } return; } sb.AppendFormat( CultureInfo.InvariantCulture, sql.ToString(), Enumerable.Range(0, sql.ParameterValues.Count) .Select(x => $"{{{this.ParameterValues.Count + x}}}") .ToArray()); foreach (var param in sql.ParameterValues) { this.ParameterValues.Add(param); } } /// /// Appends the interpolated string to this instance. /// /// The interpolated string. /// A reference to this instance after the append operation has completed. public SqlBuilder Append([InterpolatedString("")] ref AppendStringHandler handler) => this; /// /// Appends to this instance. /// /// The string. /// A reference to this instance after the append operation has completed. public SqlBuilder Append(string? text) { this.Buffer.Append(text); return this; } internal void AppendPlaceholder(object? value, string? format) { if (format == "sql") { this.Buffer.Append(CultureInfo.InvariantCulture, $"{value}"); return; } if (format == "list") { var items = (value as IEnumerable ?? (value as IEnumerable)?.Cast() ?? []) .DefaultIfEmpty(); var first = true; foreach (var item in items) { if (!first) { this.Buffer.Append(',') .Append(' '); } this.Buffer.Append('{') .Append(this.ParameterValues.Count) .Append('}'); this.ParameterValues.Add(item); first = false; } return; } var sql = value as SqlBuilder; if (sql is null) { GetDefiningQueryFromObject(value, ref sql); } if (sql is not null) { AppendPlaceholderSql(sql); return; } this.Buffer.Append('{') .Append(this.ParameterValues.Count) .Append('}'); this.ParameterValues.Add(value); } void AppendPlaceholderSql(SqlBuilder value) { var frag = new StringBuilder() .AppendLine(); AppendFragment(value, frag); frag.Replace(Environment.NewLine, $"{Environment.NewLine}\t"); this.Buffer.Append(frag); } static partial void GetDefiningQueryFromObject(object? obj, ref SqlBuilder? definingQuery); /// /// Appends the interpolated string if is true. /// /// true to append ; otherwise, false. /// The interpolated string to append. /// A reference to this instance after the append operation has completed. public SqlBuilder AppendIf(bool condition, [InterpolatedString("", nameof(condition))] ref AppendStringHandler handler) { _appendIfCondition = condition; return this; } /// /// Appends the interpolated string if is true /// and an antecedent call to /// or used a false condition. /// /// public SqlBuilder AppendElseIf(bool condition, [InterpolatedString("", nameof(condition))] ref AppendElseStringHandler handler) { if (this.AppendElseOK) { _appendIfCondition = condition; } return this; } /// /// Appends the interpolated string if an antecedent call to /// /// or used a false condition /// /// public SqlBuilder AppendElse([InterpolatedString("")] ref AppendElseStringHandler handler) { if (this.AppendElseOK) { _appendIfCondition = null; } return this; } /// /// Appends the default line terminator to this instance. /// /// A reference to this instance after the append operation has completed. public SqlBuilder AppendLine() { this.Buffer.AppendLine(); return this; } /// /// Inserts a string into this instance at the specified character position. /// /// The position in this instance where insertion begins. /// The string to insert. /// A reference to this instance after the insert operation has completed. public SqlBuilder InsertText(int index, string? value) { this.Buffer.Insert(index, value); return this; } /// /// Sets the clause identified by as the current SQL clause. /// /// The type of the SQL clause. /// A reference to this instance after the operation has completed. /// public SqlBuilder SetCurrentClause() where TClause : SqlClause, new() => SetCurrentClause(SqlClause.Instance()); /// /// Sets as the current SQL clause. /// /// The SQL clause. /// A reference to this instance after the operation has completed. /// public SqlBuilder SetCurrentClause(SqlClause? clause) { this.CurrentClause = clause; return this; } /// /// Sets the clause identified by as the next SQL clause. /// /// The type of the SQL clause. /// A reference to this instance after the operation has completed. /// public SqlBuilder SetNextClause() where TClause : SqlClause, new() => SetNextClause(SqlClause.Instance()); /// /// Sets as the next SQL clause. /// /// The SQL clause. /// A reference to this instance after the operation has completed. /// public SqlBuilder SetNextClause(SqlClause? clause) { this.NextClause = clause; return this; } /// /// Converts the value of this instance to a . /// /// A string whose value is the same as this instance. public override string ToString() => this.Buffer.ToString(); /// /// Creates and returns a copy of this instance. /// /// A new that is equivalent to this instance. public SqlBuilder Clone() => new SqlBuilder(this); #pragma warning disable IDE1006 /// /// Appends the interpolated string to the current clause. /// /// The interpolated string that represents the body of the current clause. /// A reference to this instance after the append operation has completed. [CLSCompliant(false)] public SqlBuilder _([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the to the current clause. /// /// The text that represents the body of the current clause. /// A reference to this instance after the append operation has completed. [CLSCompliant(false)] public SqlBuilder _(string? text) => AppendClause().Append(text); /// /// Appends the interpolated string to the current clause if is true. /// /// true to append to the current clause; otherwise, false. /// The interpolated string that represents the body of the current clause. /// A reference to this instance after the append operation has completed. [CLSCompliant(false)] public SqlBuilder _If(bool condition, [InterpolatedString("", nameof(condition))] ref ConditionalStringHandler handler) { _ifCondition = condition; return this; } /// /// Appends to the current clause if is true /// and an antecedent call to /// or used a false condition. /// /// [CLSCompliant(false)] public SqlBuilder _ElseIf(bool condition, [InterpolatedString("", nameof(condition))] ref ConditionalElseStringHandler handler) { if (this.ElseOK) { _ifCondition = condition; } return this; } /// /// Appends to the current clause if an antecedent call to /// /// or used a /// false condition /// /// The interpolated string that represents the body of the current clause. /// A reference to this instance after the append operation has completed. [CLSCompliant(false)] public SqlBuilder _Else([InterpolatedString("")] ref ConditionalElseStringHandler handler) => this; #pragma warning restore IDE1006 /// /// Appends the WITH clause using the provided interpolated string . /// /// The interpolated string that represents the body of the WITH clause. /// A reference to this instance after the append operation has completed. public SqlBuilder WITH([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the WITH clause using the provided . /// /// The text that represents the body of the WITH clause. /// A reference to this instance after the append operation has completed. public SqlBuilder WITH(string? text) => AppendClause().Append(text); /// /// Appends the WITH clause using the provided as body named after /// . /// /// The sub-query to use as the body of the WITH clause. /// The alias of the sub-query. /// A reference to this instance after the append operation has completed. public SqlBuilder WITH(string alias, SqlBuilder subQuery) { ArgumentNullException.ThrowIfNull(alias); ArgumentNullException.ThrowIfNull(subQuery); AppendClause(); this.Buffer.Append(alias) .Append(" AS ("); AppendPlaceholderSql(subQuery); this.Buffer.Append(')'); return this; } /// /// Sets SELECT as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder SELECT() => SetNextClause(); /// /// Appends the SELECT clause using the provided interpolated string . /// /// The interpolated string that represents the body of the SELECT clause. /// A reference to this instance after the append operation has completed. public SqlBuilder SELECT([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the SELECT clause using the provided . /// /// The text that represents the body of the SELECT clause. /// A reference to this instance after the append operation has completed. public SqlBuilder SELECT(string? text) => AppendClause().Append(text); /// /// Sets FROM as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder FROM() => SetNextClause(); /// /// Appends the FROM clause using the provided interpolated string . /// /// The interpolated string that represents the body of the FROM clause. /// A reference to this instance after the append operation has completed. public SqlBuilder FROM([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the FROM clause using the provided . /// /// The text that represents the body of the FROM clause. /// A reference to this instance after the append operation has completed. public SqlBuilder FROM(string? text) => AppendClause().Append(text); /// /// Appends the FROM clause using the provided as body named after /// . /// /// The sub-query to use as the body of the FROM clause. /// The alias of the sub-query. /// A reference to this instance after the append operation has completed. public SqlBuilder FROM(SqlBuilder subQuery, string alias) { ArgumentNullException.ThrowIfNull(subQuery); ArgumentNullException.ThrowIfNull(alias); AppendClause(); this.Buffer.Append('('); AppendPlaceholderSql(subQuery); this.Buffer.Append(") AS ") .Append(alias); return this; } /// /// Sets JOIN as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder JOIN() => SetNextClause(); /// /// Appends the JOIN clause using the provided interpolated string . /// /// The interpolated string that represents the body of the JOIN clause. /// A reference to this instance after the append operation has completed. public SqlBuilder JOIN([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the JOIN clause using the provided . /// /// The text that represents the body of the JOIN clause. /// A reference to this instance after the append operation has completed. public SqlBuilder JOIN(string? text) => AppendClause().Append(text); /// /// Sets LEFT JOIN as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder LEFT_JOIN() => SetNextClause(); /// /// Appends the LEFT JOIN clause using the provided interpolated string . /// /// The interpolated string that represents the body of the LEFT JOIN clause. /// A reference to this instance after the append operation has completed. public SqlBuilder LEFT_JOIN([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the LEFT JOIN clause using the provided . /// /// The text that represents the body of the LEFT JOIN clause. /// A reference to this instance after the append operation has completed. public SqlBuilder LEFT_JOIN(string? text) => AppendClause().Append(text); /// /// Sets RIGHT JOIN as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder RIGHT_JOIN() => SetNextClause(); /// /// Appends the RIGHT JOIN clause using the provided interpolated string . /// /// The interpolated string that represents the body of the RIGHT JOIN clause. /// A reference to this instance after the append operation has completed. public SqlBuilder RIGHT_JOIN([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the RIGHT JOIN clause using the provided . /// /// The text that represents the body of the RIGHT JOIN clause. /// A reference to this instance after the append operation has completed. public SqlBuilder RIGHT_JOIN(string? text) => AppendClause().Append(text); /// /// Sets INNER JOIN as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder INNER_JOIN() => SetNextClause(); /// /// Appends the INNER JOIN clause using the provided interpolated string . /// /// The interpolated string that represents the body of the INNER JOIN clause. /// A reference to this instance after the append operation has completed. public SqlBuilder INNER_JOIN([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the INNER JOIN clause using the provided . /// /// The text that represents the body of the INNER JOIN clause. /// A reference to this instance after the append operation has completed. public SqlBuilder INNER_JOIN(string? text) => AppendClause().Append(text); /// /// Sets CROSS JOIN as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder CROSS_JOIN() => SetNextClause(); /// /// Appends the CROSS JOIN clause using the provided interpolated string . /// /// The interpolated string that represents the body of the CROSS JOIN clause. /// A reference to this instance after the append operation has completed. public SqlBuilder CROSS_JOIN([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the CROSS JOIN clause using the provided . /// /// The text that represents the body of the CROSS JOIN clause. /// A reference to this instance after the append operation has completed. public SqlBuilder CROSS_JOIN(string? text) => AppendClause().Append(text); /// /// Sets WHERE as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder WHERE() => SetNextClause(); /// /// Appends the WHERE clause using the provided interpolated string . /// /// The interpolated string that represents the body of the WHERE clause. /// A reference to this instance after the append operation has completed. public SqlBuilder WHERE([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the WHERE clause using the provided . /// /// The text that represents the body of the WHERE clause. /// A reference to this instance after the append operation has completed. public SqlBuilder WHERE(string? text) => AppendClause().Append(text); /// /// Sets GROUP BY as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder GROUP_BY() => SetNextClause(); /// /// Appends the GROUP BY clause using the provided interpolated string . /// /// The interpolated string that represents the body of the GROUP BY clause. /// A reference to this instance after the append operation has completed. public SqlBuilder GROUP_BY([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the GROUP BY clause using the provided . /// /// The text that represents the body of the GROUP BY clause. /// A reference to this instance after the append operation has completed. public SqlBuilder GROUP_BY(string? text) => AppendClause().Append(text); /// /// Sets HAVING as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder HAVING() => SetNextClause(); /// /// Appends the HAVING clause using the provided interpolated string . /// /// The interpolated string that represents the body of the HAVING clause. /// A reference to this instance after the append operation has completed. public SqlBuilder HAVING([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the HAVING clause using the provided . /// /// The text that represents the body of the HAVING clause. /// A reference to this instance after the append operation has completed. public SqlBuilder HAVING(string? text) => AppendClause().Append(text); /// /// Sets ORDER BY as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder ORDER_BY() => SetNextClause(); /// /// Appends the ORDER BY clause using the provided interpolated string . /// /// The interpolated string that represents the body of the ORDER BY clause. /// A reference to this instance after the append operation has completed. public SqlBuilder ORDER_BY([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the ORDER BY clause using the provided . /// /// The text that represents the body of the ORDER BY clause. /// A reference to this instance after the append operation has completed. public SqlBuilder ORDER_BY(string? text) => AppendClause().Append(text); /// /// Sets LIMIT as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder LIMIT() => SetNextClause(); /// /// Appends the LIMIT clause using the provided interpolated string . /// /// The interpolated string that represents the body of the LIMIT clause. /// A reference to this instance after the append operation has completed. public SqlBuilder LIMIT([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the LIMIT clause using the provided . /// /// The text that represents the body of the LIMIT clause. /// A reference to this instance after the append operation has completed. public SqlBuilder LIMIT(string? text) => AppendClause().Append(text); /// /// Appends the LIMIT clause using the provided parameter. /// /// The value to use as parameter. /// A reference to this instance after the append operation has completed. public SqlBuilder LIMIT(int maxRecords) { AppendClause(); this.Buffer.Append('{') .Append(this.ParameterValues.Count) .Append('}'); this.ParameterValues.Add(maxRecords); return this; } /// /// Sets OFFSET as the next clause, to be used by subsequent calls to clause continuation methods, /// such as . /// /// A reference to this instance after the operation has completed. public SqlBuilder OFFSET() => SetNextClause(); /// /// Appends the OFFSET clause using the provided interpolated string . /// /// The interpolated string that represents the body of the OFFSET clause. /// A reference to this instance after the append operation has completed. public SqlBuilder OFFSET([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the OFFSET clause using the provided . /// /// The text that represents the body of the OFFSET clause. /// A reference to this instance after the append operation has completed. public SqlBuilder OFFSET(string? text) => AppendClause().Append(text); /// /// Appends the OFFSET clause using the provided parameter. /// /// The value to use as parameter. /// A reference to this instance after the append operation has completed. public SqlBuilder OFFSET(int startIndex) { AppendClause(); this.Buffer.Append('{') .Append(this.ParameterValues.Count) .Append('}'); this.ParameterValues.Add(startIndex); return this; } /// /// Appends the UNION clause. /// /// A reference to this instance after the append operation has completed. public SqlBuilder UNION() => AppendClause(); /// /// Appends the INSERT INTO clause using the provided interpolated string . /// /// The interpolated string that represents the body of the INSERT INTO clause. /// A reference to this instance after the append operation has completed. public SqlBuilder INSERT_INTO([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the INSERT INTO clause using the provided . /// /// The text that represents the body of the INSERT INTO clause. /// A reference to this instance after the append operation has completed. public SqlBuilder INSERT_INTO(string? text) => AppendClause().Append(text); /// /// Appends the DELETE FROM clause using the provided interpolated string . /// /// The interpolated string that represents the body of the DELETE FROM clause. /// A reference to this instance after the append operation has completed. public SqlBuilder DELETE_FROM([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the DELETE FROM clause using the provided . /// /// The text that represents the body of the DELETE FROM clause. /// A reference to this instance after the append operation has completed. public SqlBuilder DELETE_FROM(string? text) => AppendClause().Append(text); /// /// Appends the UPDATE clause using the provided interpolated string . /// /// The interpolated string that represents the body of the UPDATE clause. /// A reference to this instance after the append operation has completed. public SqlBuilder UPDATE([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the UPDATE clause using the provided . /// /// The text that represents the body of the UPDATE clause. /// A reference to this instance after the append operation has completed. public SqlBuilder UPDATE(string? text) => AppendClause().Append(text); /// /// Appends the SET clause using the provided interpolated string . /// /// The interpolated string that represents the body of the SET clause. /// A reference to this instance after the append operation has completed. public SqlBuilder SET([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the SET clause using the provided . /// /// The text that represents the body of the SET clause. /// A reference to this instance after the append operation has completed. public SqlBuilder SET(string? text) => AppendClause().Append(text); /// /// Appends the VALUES clause using the provided interpolated string . /// /// The interpolated string that represents the body of the VALUES clause. /// A reference to this instance after the append operation has completed. public SqlBuilder VALUES([InterpolatedString("")] ref ClauseStringHandler handler) => this; /// /// Appends the VALUES clause using the provided parameters. /// /// The parameters of the clause body. /// A reference to this instance after the append operation has completed. public SqlBuilder VALUES(params object?[] args) { ArgumentNullException.ThrowIfNull(args); if (args.Length == 0) { throw new ArgumentException($"{nameof(args)} cannot be empty", nameof(args)); } AppendClause(); this.Buffer.Append('('); for (int i = 0; i < args.Length; i++) { if (i > 0) { this.Buffer.Append(',') .Append(' '); } this.Buffer.Append('{') .Append(this.ParameterValues.Count) .Append('}'); this.ParameterValues.Add(args[i]); } this.Buffer.Append(')'); return this; } /// [EditorBrowsable(EditorBrowsableState.Never)] [InterpolatedStringHandler] public struct AppendStringHandler { internal SqlBuilder Builder { get; } /// public AppendStringHandler(int literalLength, int formattedCount, SqlBuilder sqlBuilder) { ArgumentNullException.ThrowIfNull(sqlBuilder); this.Builder = sqlBuilder; } /// public AppendStringHandler(int literalLength, int formattedCount, SqlBuilder sqlBuilder, bool condition, out bool shouldAppend) { ArgumentNullException.ThrowIfNull(sqlBuilder); this.Builder = sqlBuilder; shouldAppend = condition; } /// public void AppendLiteral(string value) => this.Builder.Buffer.Append(value); /// public void AppendFormatted(object? value, int alignment = 0, string? format = null) => this.Builder.AppendPlaceholder(value, format); } /// [EditorBrowsable(EditorBrowsableState.Never)] [InterpolatedStringHandler] public struct AppendElseStringHandler { internal SqlBuilder Builder { get; } /// public AppendElseStringHandler(int literalLength, int formattedCount, SqlBuilder sqlBuilder, out bool shouldAppend) : this(literalLength, formattedCount, sqlBuilder, true, out shouldAppend) { } /// public AppendElseStringHandler(int literalLength, int formattedCount, SqlBuilder sqlBuilder, bool condition, out bool shouldAppend) { ArgumentNullException.ThrowIfNull(sqlBuilder); this.Builder = sqlBuilder; condition = condition && sqlBuilder.AppendElseOK; shouldAppend = condition; } /// public void AppendLiteral(string value) => this.Builder.Buffer.Append(value); /// public void AppendFormatted(object? value, int alignment = 0, string? format = null) => this.Builder.AppendPlaceholder(value, format); } /// [EditorBrowsable(EditorBrowsableState.Never)] [InterpolatedStringHandler] public struct ClauseStringHandler where TClause : SqlClause, new() { internal SqlBuilder Builder { get; } /// public ClauseStringHandler(int literalLength, int formattedCount) : this(literalLength, formattedCount, new()) { } /// public ClauseStringHandler(int literalLength, int formattedCount, SqlBuilder sqlBuilder) { ArgumentNullException.ThrowIfNull(sqlBuilder); this.Builder = sqlBuilder; sqlBuilder.AppendClause(); } /// public void AppendLiteral(string value) => this.Builder.Buffer.Append(value); /// public void AppendFormatted(object? value, int alignment = 0, string? format = null) => this.Builder.AppendPlaceholder(value, format); } /// [EditorBrowsable(EditorBrowsableState.Never)] [InterpolatedStringHandler] public struct ConditionalStringHandler { readonly SqlBuilder _sqlBuilder; /// public ConditionalStringHandler(int literalLength, int formattedCount, SqlBuilder sqlBuilder, bool condition, out bool shouldAppend) { ArgumentNullException.ThrowIfNull(sqlBuilder); _sqlBuilder = sqlBuilder; shouldAppend = condition; if (shouldAppend) { sqlBuilder.AppendClause(); } } /// public void AppendLiteral(string value) => _sqlBuilder.Buffer.Append(value); /// public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _sqlBuilder.AppendPlaceholder(value, format); } /// [EditorBrowsable(EditorBrowsableState.Never)] [InterpolatedStringHandler] public struct ConditionalElseStringHandler { readonly SqlBuilder _sqlBuilder; /// public ConditionalElseStringHandler(int literalLength, int formattedCount, SqlBuilder sqlBuilder, out bool shouldAppend) : this(literalLength, formattedCount, sqlBuilder, true, out shouldAppend) { } /// public ConditionalElseStringHandler(int literalLength, int formattedCount, SqlBuilder sqlBuilder, bool condition, out bool shouldAppend) { ArgumentNullException.ThrowIfNull(sqlBuilder); _sqlBuilder = sqlBuilder; condition = condition && sqlBuilder.ElseOK; shouldAppend = condition; if (shouldAppend) { sqlBuilder.AppendClause(); } } /// public void AppendLiteral(string value) => _sqlBuilder.Buffer.Append(value); /// public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _sqlBuilder.AppendPlaceholder(value, format); } } /// /// Provides a set of static (Shared in Visual Basic) methods to create /// instances. /// public static partial class SQL { /// /// Creates and returns a new initialized by /// appending the WITH clause using the provided string interpolated . /// /// The body of the WITH clause. /// /// A new after calling . /// public static SqlBuilder WITH(ref SqlBuilder.ClauseStringHandler handler) => handler.Builder; /// /// Creates and returns a new initialized by /// appending the WITH clause using the provided . /// /// The body of the WITH clause. /// /// A new after calling . /// public static SqlBuilder WITH(string? text) => new SqlBuilder().WITH(text); /// /// Creates and returns a new initialized by /// appending the WITH clause using the provided /// and . /// /// The alias of the sub-query. /// The sub-query to use as the body of the WITH clause. /// /// A new after calling . /// public static SqlBuilder WITH(string alias, SqlBuilder subQuery) { ArgumentNullException.ThrowIfNull(alias); ArgumentNullException.ThrowIfNull(subQuery); return new SqlBuilder().WITH(alias, subQuery); } /// /// Creates and returns a new initialized by /// appending the SELECT clause using the provided string interpolated . /// /// The body of the SELECT clause. /// /// A new after calling . /// public static SqlBuilder SELECT(ref SqlBuilder.ClauseStringHandler handler) => handler.Builder; /// /// Creates and returns a new initialized by /// appending the SELECT clause using the provided . /// /// The body of the SELECT clause. /// /// A new after calling . /// public static SqlBuilder SELECT(string? text) => new SqlBuilder().SELECT(text); /// /// Creates and returns a new initialized by /// appending the INSERT INTO clause using the provided string interpolated . /// /// The body of the INSERT INTO clause. /// /// A new after calling . /// public static SqlBuilder INSERT_INTO(ref SqlBuilder.ClauseStringHandler handler) => handler.Builder; /// /// Creates and returns a new initialized by /// appending the INSERT INTO clause using the provided . /// /// The body of the INSERT INTO clause. /// /// A new after calling . /// public static SqlBuilder INSERT_INTO(string? text) => new SqlBuilder().INSERT_INTO(text); /// /// Creates and returns a new initialized by /// appending the UPDATE clause using the provided string interpolated . /// /// The body of the UPDATE clause. /// /// A new after calling . /// public static SqlBuilder UPDATE(ref SqlBuilder.ClauseStringHandler handler) => handler.Builder; /// /// Creates and returns a new initialized by /// appending the UPDATE clause using the provided . /// /// The body of the UPDATE clause. /// /// A new after calling . /// public static SqlBuilder UPDATE(string? text) => new SqlBuilder().UPDATE(text); /// /// Creates and returns a new initialized by /// appending the DELETE FROM clause using the provided string interpolated . /// /// The body of the DELETE FROM clause. /// /// A new after calling . /// public static SqlBuilder DELETE_FROM(ref SqlBuilder.ClauseStringHandler handler) => handler.Builder; /// /// Creates and returns a new initialized by /// appending the DELETE FROM clause using the provided . /// /// The body of the DELETE FROM clause. /// /// A new after calling . /// public static SqlBuilder DELETE_FROM(string? text) => new SqlBuilder().DELETE_FROM(text); // Object Members /// [EditorBrowsable(EditorBrowsableState.Never)] public static new bool Equals(object? objectA, object? objectB) => Object.Equals(objectA, objectB); /// [EditorBrowsable(EditorBrowsableState.Never)] public static new bool ReferenceEquals(object? objectA, object? objectB) => Object.ReferenceEquals(objectA, objectB); } /// /// Provides information about a SQL clause. Used by . /// /// The name of the clause. /// The string to use for consecutive calls. public abstract record class SqlClause(string? Name, string? Separator) { /// /// The "current" clause. /// /// public sealed record class Current() : SqlClause(null, null); /// /// The WITH clause. /// /// public sealed record class WITH() : SqlClause("WITH", null); /// /// The SELECT clause. /// /// public sealed record class SELECT() : SqlClause("SELECT", ", "); /// /// The FROM clause. /// /// public sealed record class FROM() : SqlClause("FROM", ", "); /// /// The JOIN clause. /// /// public sealed record class JOIN() : SqlClause("JOIN", null); /// /// The LEFT JOIN clause. /// /// public sealed record class LEFT_JOIN() : SqlClause("LEFT JOIN", null); /// /// The RIGHT JOIN clause. /// /// public sealed record class RIGHT_JOIN() : SqlClause("RIGHT JOIN", null); /// /// The INNER JOIN clause. /// /// public sealed record class INNER_JOIN() : SqlClause("INNER JOIN", null); /// /// The CROSS JOIN clause. /// /// public sealed record class CROSS_JOIN() : SqlClause("CROSS JOIN", null); /// /// The WHERE clause. /// /// public sealed record class WHERE() : SqlClause("WHERE", " AND "); /// /// The GROUP BY clause. /// /// public sealed record class GROUP_BY() : SqlClause("GROUP BY", ", "); /// /// The HAVING clause. /// /// public sealed record class HAVING() : SqlClause("HAVING", " AND "); /// /// The ORDER BY clause. /// /// public sealed record class ORDER_BY() : SqlClause("ORDER BY", ", "); /// /// The LIMIT clause. /// /// public sealed record class LIMIT() : SqlClause("LIMIT", null); /// /// The OFFSET clause. /// /// public sealed record class OFFSET() : SqlClause("OFFSET", null); /// /// The UNION clause. /// /// public sealed record class UNION() : SqlClause("UNION", null); /// /// The INSERT INTO clause. /// /// public sealed record class INSERT_INTO() : SqlClause("INSERT INTO", null); /// /// The DELETE FROM clause. /// /// public sealed record class DELETE_FROM() : SqlClause("DELETE FROM", null); /// /// The UPDATE clause. /// /// public sealed record class UPDATE() : SqlClause("UPDATE", null); /// /// The SET clause. /// /// public sealed record class SET() : SqlClause("SET", ", "); /// /// The VALUES clause. /// /// public sealed record class VALUES() : SqlClause("VALUES", "," + Environment.NewLine); /// /// Gets a singleton instance of the clause identified by . /// /// The type of the clause. /// An instance of . public static TClause Instance() where TClause : SqlClause, new() => InstanceClass.Value; static class InstanceClass where TClause : SqlClause, new() { internal static readonly TClause Value = new(); } } ================================================ FILE: src/DbExtensions/SqlSet.Async.cs ================================================ // Copyright 2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace DbExtensions; #nullable enable partial class SqlSet { private protected virtual IAsyncEnumerable AsyncMap(bool singleResult) { var query = GetDefiningQuery(clone: false); var results = default(IAsyncEnumerable); if (_resultType is not null) { PocoAsyncMap(singleResult, query, ref results); return results ?? throw new InvalidOperationException("Cannot enumerate this set."); } DynamicAsyncMap(singleResult, query, ref results); return results ?? throw new InvalidOperationException("Cannot enumerate this set unless you specify a result type."); } partial void PocoAsyncMap(bool singleResult, SqlBuilder query, ref IAsyncEnumerable? results); partial void DynamicAsyncMap(bool singleResult, SqlBuilder query, ref IAsyncEnumerable? results); // ISqlSet Members /// public IAsyncEnumerable AsAsyncEnumerable() => AsAsyncEnumerable(singleResult: false); IAsyncEnumerable AsAsyncEnumerable(bool singleResult) => AsyncMap(singleResult); /// /// public async ValueTask AllAsync(string predicate, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(predicate); return !await AnyAsync(String.Concat("NOT (", predicate, ")"), cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask AllAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { var builder = predicate.Fragment; builder.Buffer.Insert(0, "NOT (") .Append(')'); return !await AnyAsync(predicate, cancellationToken) .ConfigureAwait(false); } /// /// The to monitor for cancellation requests. The default is . public async ValueTask AnyAsync(CancellationToken cancellationToken = default) { var (query, mapFn) = AnyImplParams(); return await _db.AsyncMap(query, mapFn) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask AnyAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .AnyAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask AnyAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .AnyAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask CountAsync(CancellationToken cancellationToken = default) { var (query, mapFn) = CountImplParams(); return await _db.AsyncMap(query, mapFn) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask CountAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .CountAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask CountAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .CountAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask FirstAsync(CancellationToken cancellationToken = default) { return await Take(1) .AsAsyncEnumerable(singleResult: true) .FirstAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask FirstAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .FirstAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask FirstAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .FirstAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask FirstOrDefaultAsync(CancellationToken cancellationToken = default) { return await Take(1) .AsAsyncEnumerable(singleResult: true) .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask FirstOrDefaultAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask FirstOrDefaultAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// Returns an async enumerator that iterates through the set. /// /// A for the set. /// public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => AsAsyncEnumerable().GetAsyncEnumerator(cancellationToken); /// /// public async ValueTask LongCountAsync(CancellationToken cancellationToken = default) { var (query, mapFn) = LongCountImplParams(); return await _db.AsyncMap(query, mapFn) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask LongCountAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .LongCountAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask LongCountAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .LongCountAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask SingleAsync(CancellationToken cancellationToken = default) { return await AsAsyncEnumerable(singleResult: true) .SingleAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask SingleAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .SingleAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask SingleAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .SingleAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask SingleOrDefaultAsync(CancellationToken cancellationToken = default) { return await AsAsyncEnumerable(singleResult: true) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask SingleOrDefaultAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask SingleOrDefaultAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask ToArrayAsync(CancellationToken cancellationToken = default) { return await AsAsyncEnumerable() .ToArrayAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask> ToListAsync(CancellationToken cancellationToken = default) { return await AsAsyncEnumerable() .ToListAsync(cancellationToken) .ConfigureAwait(false); } } partial class SqlSet { private protected override IAsyncEnumerable AsyncMap(bool singleResult) { if (_explicitMapper is not null) { return _db.AsyncMap( GetDefiningQuery(clone: false), r => (object)_explicitMapper.Invoke(r)!); } return base.AsyncMap(singleResult); } IAsyncEnumerable AsyncMapTyped(bool singleResult) { var query = GetDefiningQuery(clone: false); if (_explicitMapper is not null) { return _db.AsyncMap(query, _explicitMapper); } var results = default(IAsyncEnumerable); PocoAsyncMap(singleResult, query, ref results); return results ?? throw new InvalidOperationException("Cannot enumerate this set."); } partial void PocoAsyncMap(bool singleResult, SqlBuilder query, ref IAsyncEnumerable? results); // ISqlSet Members /// public new IAsyncEnumerable AsAsyncEnumerable() => AsAsyncEnumerable(singleResult: false); IAsyncEnumerable AsAsyncEnumerable(bool singleResult) => AsyncMapTyped(singleResult); /// public new async ValueTask FirstAsync(CancellationToken cancellationToken = default) { return await Take(1) .AsAsyncEnumerable(singleResult: true) .FirstAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask FirstAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .FirstAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask FirstAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .FirstAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask FirstOrDefaultAsync(CancellationToken cancellationToken = default) { return await Take(1) .AsAsyncEnumerable(singleResult: true) .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask FirstOrDefaultAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask FirstOrDefaultAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// Returns an async enumerator that iterates through the set. /// /// A for the set. /// public new IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => AsAsyncEnumerable().GetAsyncEnumerator(cancellationToken); /// public new async ValueTask SingleAsync(CancellationToken cancellationToken = default) { return await AsAsyncEnumerable(singleResult: true) .SingleAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask SingleAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .SingleAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask SingleAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .SingleAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask SingleOrDefaultAsync(CancellationToken cancellationToken = default) { return await AsAsyncEnumerable(singleResult: true) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask SingleOrDefaultAsync(string predicate, CancellationToken cancellationToken = default) { return await Where(predicate) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask SingleOrDefaultAsync(OperatorStringHandler predicate, CancellationToken cancellationToken = default) { return await Where(ref predicate) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// public new async ValueTask ToArrayAsync(CancellationToken cancellationToken = default) { return await AsAsyncEnumerable() .ToArrayAsync(cancellationToken) .ConfigureAwait(false); } /// /// public new async ValueTask> ToListAsync(CancellationToken cancellationToken = default) { return await AsAsyncEnumerable() .ToListAsync(cancellationToken) .ConfigureAwait(false); } } partial interface ISqlSet { ValueTask AllAsync(string predicate, CancellationToken cancellationToken); ValueTask AllAsync(SqlSet.OperatorStringHandler predicate, CancellationToken cancellationToken); ValueTask AnyAsync(CancellationToken cancellationToken); ValueTask AnyAsync(string predicate, CancellationToken cancellationToken); IAsyncEnumerable AsAsyncEnumerable(); ValueTask CountAsync(CancellationToken cancellationToken); ValueTask CountAsync(string predicate, CancellationToken cancellationToken); ValueTask CountAsync(SqlSet.OperatorStringHandler predicate, CancellationToken cancellationToken); ValueTask FirstAsync(CancellationToken cancellationToken); ValueTask FirstAsync(string predicate, CancellationToken cancellationToken); ValueTask FirstAsync(SqlSet.OperatorStringHandler predicate, CancellationToken cancellationToken); ValueTask FirstOrDefaultAsync(CancellationToken cancellationToken); ValueTask FirstOrDefaultAsync(string predicate, CancellationToken cancellationToken); ValueTask FirstOrDefaultAsync(SqlSet.OperatorStringHandler predicate, CancellationToken cancellationToken); IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken); ValueTask LongCountAsync(CancellationToken cancellationToken); ValueTask LongCountAsync(string predicate, CancellationToken cancellationToken); ValueTask LongCountAsync(SqlSet.OperatorStringHandler predicate, CancellationToken cancellationToken); ValueTask SingleAsync(CancellationToken cancellationToken); ValueTask SingleAsync(string predicate, CancellationToken cancellationToken); ValueTask SingleAsync(SqlSet.OperatorStringHandler predicate, CancellationToken cancellationToken); ValueTask SingleOrDefaultAsync(CancellationToken cancellationToken); ValueTask SingleOrDefaultAsync(string predicate, CancellationToken cancellationToken); ValueTask SingleOrDefaultAsync(SqlSet.OperatorStringHandler predicate, CancellationToken cancellationToken); ValueTask ToArrayAsync(CancellationToken cancellationToken); ValueTask> ToListAsync(CancellationToken cancellationToken); } ================================================ FILE: src/DbExtensions/SqlSet.cs ================================================ // Copyright 2012-2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data.Common; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; namespace DbExtensions; #nullable enable partial class SqlBuilder { /// /// Appends the WITH clause using the provided as body named after /// . /// /// The sub-query to use as the body of the WITH clause. /// The alias of the sub-query. /// A reference to this instance after the append operation has completed. public SqlBuilder WITH(string alias, SqlSet subQuery) { ArgumentNullException.ThrowIfNull(alias); ArgumentNullException.ThrowIfNull(subQuery); return WITH(alias, subQuery.GetDefiningQuery()); } /// /// Appends the FROM clause using the provided as body named after /// . /// /// The sub-query to use as the body of the FROM clause. /// The alias of the sub-query. /// A reference to this instance after the append operation has completed. public SqlBuilder FROM(SqlSet subQuery, string alias) { ArgumentNullException.ThrowIfNull(subQuery); ArgumentNullException.ThrowIfNull(alias); return FROM(subQuery.GetDefiningQuery(), alias); } static partial void GetDefiningQueryFromObject(object? obj, ref SqlBuilder? definingQuery) => definingQuery = (obj as SqlSet)?.GetDefiningQuery(); } static partial class SQL { /// /// Creates and returns a new initialized by /// appending the WITH clause using the provided /// and . /// /// The alias of the sub-query. /// The sub-query to use as the body of the WITH clause. /// /// A new after calling . /// public static SqlBuilder WITH(string alias, SqlSet subQuery) { ArgumentNullException.ThrowIfNull(alias); ArgumentNullException.ThrowIfNull(subQuery); return new SqlBuilder().WITH(alias, subQuery); } } partial class Database { /// /// Creates and returns a new using the provided table name. /// /// The name of the table that will be the source of data for the set. /// A new object. public SqlSet From(string tableName) => From(tableName, null); /// /// The type of objects to map the results to. public SqlSet From(string tableName, Type? resultType) { ArgumentNullException.ThrowIfNull(tableName); return new SqlSet([tableName, null], resultType, this); } /// /// Creates and returns a new using the provided table name. /// /// The type of objects to map the results to. /// The name of the table that will be the source of data for the set. /// A new object. public SqlSet From(string tableName) { ArgumentNullException.ThrowIfNull(tableName); return new SqlSet([tableName, null], this); } /// This method is used by auto-generated "table" classes. /// [EditorBrowsable(EditorBrowsableState.Never)] public SqlSet From(string tableName, string columnList) { ArgumentNullException.ThrowIfNull(tableName); return new SqlSet([tableName, columnList], this); } /// /// Creates and returns a new using the provided defining query. /// /// The SQL query that will be the source of data for the set. /// A new object. public SqlSet FromQuery(SqlBuilder definingQuery) => FromQuery(definingQuery, null); /// /// The type of objects to map the results to. public SqlSet FromQuery(SqlBuilder definingQuery, Type? resultType) { ArgumentNullException.ThrowIfNull(definingQuery); return new SqlSet(definingQuery, resultType, this); } /// /// Creates and returns a new using the provided defining query. /// /// The type of objects to map the results to. /// The SQL query that will be the source of data for the set. /// A new object. public SqlSet FromQuery(SqlBuilder definingQuery) { ArgumentNullException.ThrowIfNull(definingQuery); return new SqlSet(definingQuery, this); } /// /// Creates and returns a new using the provided defining query and mapper. /// /// /// A custom mapper function that creates instances from the rows in the set. public SqlSet FromQuery(SqlBuilder definingQuery, Func mapper) { ArgumentNullException.ThrowIfNull(definingQuery); ArgumentNullException.ThrowIfNull(mapper); return new SqlSet(definingQuery, mapper, this); } } /// /// Represents an immutable, connected SQL query. /// This class cannot be instantiated, to get an instance use one of the /// or /// overloads. /// /// For information on how to use SqlSet see SqlSet Tutorial. public partial class SqlSet : ISqlSet { // definingQuery should NEVER be modified readonly SqlBuilder? _definingQuery; readonly string?[]? _fromSelect; readonly Type? _resultType; readonly SqlBuffer _buffer; private protected readonly Database _db; readonly int _setIndex = 1; /// /// The type of objects this set returns. This property can be null. /// public Type? ResultType => _resultType; /// /// The this set is connected to. /// public Database Database => _db; internal SqlSet(SqlBuilder definingQuery, Type? resultType, Database db) { _definingQuery = definingQuery.Clone(); _resultType = resultType; _db = db; } internal SqlSet(string?[] fromSelect, Type? resultType, Database db) { Debug.Assert(fromSelect.Length == 2); _fromSelect = fromSelect; _resultType = resultType; _db = db; } private protected SqlSet(SqlSet set, SqlBuilder superQuery, Type? resultType, SqlBuffer? buffer) : this(set, resultType, buffer) { _definingQuery = superQuery; } private protected SqlSet(SqlSet set, string?[] fromSelect, Type? resultType, SqlBuffer? buffer) : this(set, resultType, buffer) { Debug.Assert(fromSelect.Length == 2); _fromSelect = fromSelect; } private SqlSet(SqlSet set, Type? resultType, SqlBuffer? buffer) { _resultType = resultType ?? set._resultType; _setIndex += set._setIndex; _db = set._db; if (buffer is not null) { _buffer = buffer.Value; } Initialize2(set); } partial void Initialize2(SqlSet set); /// /// Returns the SQL query that is the source of data for the set. /// /// The SQL query that is the source of data for the set public SqlBuilder GetDefiningQuery() => GetDefiningQuery(clone: true); private protected SqlBuilder GetDefiningQuery(bool clone = true, bool ignoreBuffer = false, bool super = false, ISqlFragment? select = null) { if (!ignoreBuffer && _buffer.HasValue) { return BuildQuery(select); } var query = _definingQuery; if (query is null) { Debug.Assert(_fromSelect is not null); query = new SqlBuilder() .SELECT(String.Empty); if (select is not null) { query.AppendFragment(select); } else { query.Append(_fromSelect[1] ?? "*"); } query.FROM(_fromSelect[0]); } else if (super || select is not null) { query = CreateSuperQuery(query, select); } else if (clone) { query = query.Clone(); } return query; } SqlBuilder BuildQuery(ISqlFragment? select) { switch (_db.Configuration.SqlDialect) { case SqlDialect.Default: return BuildQuery_Default(select); case SqlDialect.TSql: return BuildQuery_TSql(select); default: throw new NotImplementedException(); } } SqlBuilder BuildQuery_Default(ISqlFragment? select) { var whereBuffer = _buffer.Where; var orderByBuffer = _buffer.OrderBy; var skipBuffer = _buffer.Skip; var takeBuffer = _buffer.Take; var hasWhere = whereBuffer is not null; var hasOrderBy = orderByBuffer is not null; var hasSkip = skipBuffer.HasValue; var hasTake = takeBuffer.HasValue; var query = GetDefiningQuery(ignoreBuffer: true, super: true, select: select); if (hasWhere) { query.WHERE(String.Empty) .AppendFragment(whereBuffer!); } if (hasOrderBy) { query.ORDER_BY(String.Empty) .AppendFragment(orderByBuffer!); } if (hasTake) { query.LIMIT(takeBuffer!.Value); } if (hasSkip) { query.OFFSET(skipBuffer!.Value); } return query; } SqlBuilder BuildQuery_TSql(ISqlFragment? select) { var whereBuffer = _buffer.Where; var orderByBuffer = _buffer.OrderBy; var skipBuffer = _buffer.Skip; var takeBuffer = _buffer.Take; var hasWhere = whereBuffer is not null; var hasOrderBy = orderByBuffer is not null; var hasSkip = skipBuffer.HasValue; var hasTake = takeBuffer.HasValue; if (hasSkip) { var query = GetDefiningQuery(ignoreBuffer: true, super: true, select: select); if (hasWhere) { query.WHERE(String.Empty) .AppendFragment(whereBuffer!); } if (hasOrderBy) { query.ORDER_BY(String.Empty) .AppendFragment(orderByBuffer!); } else { // Cannot have OFFSET without ORDER BY query.ORDER_BY("1"); } query.OFFSET($"{skipBuffer!.Value} ROWS"); if (hasTake) { query.AppendClause() .Append($"NEXT {takeBuffer!.Value} ROWS ONLY"); } return query; } else if (hasTake) { var topSelect = new SqlFragment("TOP({0}) *", (object[])[takeBuffer!.Value]); var query = GetDefiningQuery(ignoreBuffer: true, super: true, select: topSelect); if (hasWhere) { query.WHERE(String.Empty) .AppendFragment(whereBuffer!); } if (hasOrderBy) { query.ORDER_BY(String.Empty) .AppendFragment(orderByBuffer!); } if (select is not null) { // SELECT must be done in super query, it could remove columns used by WHERE/ORDER BY query = CreateSuperQuery(query, select); } return query; } else { var query = GetDefiningQuery(ignoreBuffer: true, super: true, select: select); if (hasWhere) { query.WHERE(String.Empty) .AppendFragment(whereBuffer!); } if (hasOrderBy) { query.ORDER_BY(String.Empty) .AppendFragment(orderByBuffer!); // The ORDER BY clause is invalid in subqueries, unless TOP, OFFSET or FOR XML is also specified. query.OFFSET("0 ROWS"); } return query; } } SqlBuilder CreateSuperQuery(SqlBuilder query, ISqlFragment? select) { var superQuery = new SqlBuilder() .SELECT(String.Empty); if (select is not null) { superQuery.AppendFragment(select); } else { superQuery.Buffer.Append('*'); } superQuery.FROM(query, $"dbex_set{_setIndex}"); return superQuery; } private protected virtual SqlSet CreateSet(SqlBuilder superQuery, Type? resultType = null, SqlBuffer? buffer = null) => new SqlSet(this, superQuery, resultType, buffer); private protected virtual SqlSet CreateSet(string?[] fromSelect, Type? resultType = null, SqlBuffer? buffer = null) => new SqlSet(this, fromSelect, resultType, buffer); SqlSet CreateSet(SqlBuilder superQuery, Func? mapper = null, SqlBuffer? buffer = null) => new SqlSet(this, superQuery, mapper, buffer); SqlSet CreateSet(string?[] fromSelect, SqlBuffer? buffer = null) => new SqlSet(this, fromSelect, buffer); private protected SqlSet Clone() => CreateBufferedSet(ignoreBuffer: true, buffer: _buffer); SqlSet CreateBufferedSet(bool ignoreBuffer, SqlBuffer buffer, Type? resultType = null) { if (ignoreBuffer && _definingQuery is null) { Debug.Assert(_fromSelect is not null); return CreateSet(_fromSelect, resultType, buffer); } var query = GetDefiningQuery(ignoreBuffer: ignoreBuffer); return CreateSet(query, resultType, buffer); } SqlSet CreateBufferedSet(bool ignoreBuffer, SqlBuffer buffer) { if (ignoreBuffer && _definingQuery is null) { Debug.Assert(_fromSelect is not null); return CreateSet(_fromSelect, buffer); } var query = GetDefiningQuery(ignoreBuffer: ignoreBuffer); return CreateSet(query, default(Func), buffer); } private protected virtual IEnumerable Map(bool singleResult) { var query = GetDefiningQuery(clone: false); var results = default(IEnumerable); if (_resultType is not null) { PocoMap(singleResult, query, ref results); return results ?? throw new InvalidOperationException("Cannot enumerate this set."); } DynamicMap(singleResult, query, ref results); return results ?? throw new InvalidOperationException("Cannot enumerate this set unless you specify a result type."); } partial void PocoMap(bool singleResult, SqlBuilder query, ref IEnumerable? results); partial void DynamicMap(bool singleResult, SqlBuilder query, ref IEnumerable? results); // ISqlSet Members /// /// Determines whether all elements of the set satisfy a condition. /// /// A SQL expression to test each row for a condition. /// true if every element of the set passes the test in the specified , or if the set is empty; otherwise, false. public bool All(string predicate) { ArgumentNullException.ThrowIfNull(predicate); return !Any(String.Concat("NOT (", predicate, ")")); } /// public bool All(ref OperatorStringHandler predicate) { var builder = predicate.Fragment; builder.Buffer.Insert(0, "NOT (") .Append(')'); return !Any(ref predicate); } /// /// Determines whether the set contains any elements. /// /// true if the sequence contains any elements; otherwise, false. public bool Any() { var (query, mapFn) = AnyImplParams(); return _db.Map(query, mapFn) .SingleOrDefault(); } (SqlBuilder, Func) AnyImplParams() { var query = new SqlBuilder() .SELECT($"(CASE WHEN EXISTS ({GetDefiningQuery(clone: false)}) THEN 1 ELSE 0 END)"); return (query, mapFn); static bool mapFn(DbDataReader r) => Convert.ToInt32(r[0], CultureInfo.InvariantCulture) != 0; } /// /// Determines whether any element of the set satisfies a condition. /// /// A SQL expression to test each row for a condition. /// true if any elements in the set pass the test in the specified ; otherwise, false. public bool Any(string predicate) => Where(predicate).Any(); /// public bool Any(ref OperatorStringHandler predicate) => Where(ref predicate).Any(); /// /// Gets all elements in the set. The query is deferred-executed. /// /// All elements in the set. public IEnumerable AsEnumerable() => AsEnumerable(singleResult: false); IEnumerable AsEnumerable(bool singleResult) => Map(singleResult).Cast(); /// /// Casts the elements of the set to the specified type. /// /// The type to cast the elements of the set to. /// A new that contains each element of the current set cast to the specified type. public SqlSet Cast() { if (_resultType is not null && _resultType != typeof(TResult)) { throw new InvalidOperationException("The specified type parameter is not valid for this instance."); } return CreateBufferedSet(ignoreBuffer: true, buffer: _buffer); } /// /// Casts the elements of the set to the specified type. /// /// The type to cast the elements of the set to. /// A new that contains each element of the current set cast to the specified type. public SqlSet Cast(Type resultType) { ArgumentNullException.ThrowIfNull(resultType); if (_resultType is not null && _resultType != resultType) { throw new InvalidOperationException("The specified resultType is not valid for this instance."); } return CreateBufferedSet(ignoreBuffer: true, buffer: _buffer, resultType: resultType); } /// /// Returns the number of elements in the set. /// /// The number of elements in the set. /// The number of elements is larger than . public int Count() { var (query, mapFn) = CountImplParams(); return _db.Map(query, mapFn) .SingleOrDefault(); } /// /// Returns a number that represents how many elements in the set satisfy a condition. /// /// A SQL expression to test each row for a condition. /// A number that represents how many elements in the set satisfy the condition in the . /// The number of matching elements exceeds . public int Count(string predicate) => Where(predicate).Count(); /// public int Count(ref OperatorStringHandler predicate) => Where(ref predicate).Count(); (SqlBuilder, Func) CountImplParams() { var query = new SqlBuilder() .SELECT("COUNT(*)") .FROM(GetDefiningQuery(clone: false), "dbex_count"); return (query, mapFn); static int mapFn(DbDataReader r) => Convert.ToInt32(!r.IsDBNull(0) ? r.GetValue(0) : null, CultureInfo.InvariantCulture); } /// /// Returns the first element of the set. /// /// The first element in the set. /// The set is empty. public object First() => Take(1).AsEnumerable(singleResult: true).First(); /// /// Returns the first element in the set that satisfies a specified condition. /// /// A SQL expression to test each row for a condition. /// The first element in the set that passes the test in the specified . /// No element satisfies the condition in .-or-The set is empty. public object First(string predicate) => Where(predicate).First(); /// public object First(ref OperatorStringHandler predicate) => Where(ref predicate).First(); /// /// Returns the first element of the set, or a default value if the set contains no elements. /// /// A default value if the set is empty; otherwise, the first element. public object? FirstOrDefault() => Take(1).AsEnumerable(singleResult: true).FirstOrDefault(); /// /// Returns the first element of the set that satisfies a condition or a default value if no such element is found. /// /// A SQL expression to test each row for a condition. /// /// A default value if the set is empty or if no element passes the test specified by ; otherwise, the /// first element that passes the test specified by . /// public object? FirstOrDefault(string predicate) => Where(predicate).FirstOrDefault(); /// public object? FirstOrDefault(ref OperatorStringHandler predicate) => Where(ref predicate).FirstOrDefault(); /// /// Returns an enumerator that iterates through the set. /// /// A for the set. public IEnumerator GetEnumerator() => AsEnumerable().GetEnumerator(); /// /// Returns an that represents the total number of elements in the set. /// /// The number of elements in the set. /// The number of elements is larger than . public long LongCount() { var (query, mapFn) = LongCountImplParams(); return _db.Map(query, mapFn) .SingleOrDefault(); } /// /// Returns an that represents how many elements in the set satisfy a condition. /// /// A SQL expression to test each row for a condition. /// A number that represents how many elements in the set satisfy the condition in the . /// The number of matching elements exceeds . public long LongCount(string predicate) => Where(predicate).LongCount(); /// public long LongCount(ref OperatorStringHandler predicate) => Where(ref predicate).LongCount(); (SqlBuilder, Func) LongCountImplParams() { var query = new SqlBuilder() .SELECT("COUNT(*)") .FROM(GetDefiningQuery(clone: false), "dbex_count"); return (query, mapFn); static long mapFn(DbDataReader r) => Convert.ToInt64(!r.IsDBNull(0) ? r.GetValue(0) : null, CultureInfo.InvariantCulture); } /// /// Sorts the elements of the set according to the . /// /// The list of columns to base the sort on. /// A new whose elements are sorted according to . public SqlSet OrderBy(string columnList) { ArgumentNullException.ThrowIfNull(columnList); return OrderBy(new SqlFragment(columnList)); } /// public SqlSet OrderBy(ref OperatorStringHandler columnList) => OrderBy(columnList.Fragment); SqlSet OrderBy(ISqlFragment fragment) { var ignoreBuffer = _buffer.OrderBy is null && _buffer.Skip is null && _buffer.Take is null; var newBuffer = new SqlBuffer( Where: (ignoreBuffer) ? _buffer.Where : null, OrderBy: fragment); var set = CreateBufferedSet(ignoreBuffer, newBuffer); return set; } /// /// Projects each element of the set into a new form. /// /// The type that maps to. /// The list of columns that maps to properties on . /// A new . public SqlSet Select(string columnList) { ArgumentNullException.ThrowIfNull(columnList); return CreateSet(GetDefiningQuery(select: new SqlFragment(columnList))); } /// public SqlSet Select(ref OperatorStringHandler columnList) => CreateSet(GetDefiningQuery(select: columnList.Fragment)); /// /// Projects each element of the set into a new form. /// /// The type that returns. /// The list of columns that are used by . /// A custom mapper function that creates instances from the rows in the set. /// A new . public SqlSet Select(string columnList, Func mapper) { ArgumentNullException.ThrowIfNull(mapper); ArgumentNullException.ThrowIfNull(columnList); return CreateSet(GetDefiningQuery(select: new SqlFragment(columnList)), mapper); } /// public SqlSet Select(ref OperatorStringHandler columnList, Func mapper) { ArgumentNullException.ThrowIfNull(mapper); return CreateSet(GetDefiningQuery(select: columnList.Fragment), mapper); } /// /// Projects each element of the set into a new form. /// /// The list of columns that maps to properties on . /// The type that maps to. /// A new . public SqlSet Select(string columnList, Type resultType) { ArgumentNullException.ThrowIfNull(resultType); ArgumentNullException.ThrowIfNull(columnList); return CreateSet(GetDefiningQuery(select: new SqlFragment(columnList)), resultType); } /// public SqlSet Select(ref OperatorStringHandler columnList, Type resultType) { ArgumentNullException.ThrowIfNull(resultType); return CreateSet(GetDefiningQuery(select: columnList.Fragment), resultType); } /// /// Projects each element of the set into a new form. /// /// The list of columns to select. /// A new . public SqlSet Select(string columnList) { ArgumentNullException.ThrowIfNull(columnList); return CreateSet(GetDefiningQuery(select: new SqlFragment(columnList))); } /// public SqlSet Select(ref OperatorStringHandler columnList) => CreateSet(GetDefiningQuery(select: columnList.Fragment)); /// /// The single element of the set. /// /// The single element of the set. /// The set contains more than one element.-or-The set is empty. public object Single() => AsEnumerable(singleResult: true).Single(); /// /// Returns the only element of the set that satisfies a specified condition, and throws an exception if more than one such element exists. /// /// A SQL expression to test each row for a condition. /// The single element of the set that passes the test in the specified . /// No element satisfies the condition in .-or-More than one element satisfies the condition in .-or-The set is empty. public object Single(string predicate) => Where(predicate).Single(); /// public object Single(ref OperatorStringHandler predicate) => Where(ref predicate).Single(); /// /// Returns the only element of the set, or a default value if the set is empty; this method throws an exception if there is more than one element in the set. /// /// The single element of the set, or a default value if the set contains no elements. /// The set contains more than one element. public object? SingleOrDefault() => AsEnumerable(singleResult: true).SingleOrDefault(); /// /// Returns the only element of the set that satisfies a specified condition or a default value if no such element exists; this method throws an exception if more than one element satisfies the condition. /// /// A SQL expression to test each row for a condition. /// The single element of the set that satisfies the condition, or a default value if no such element is found. public object? SingleOrDefault(string predicate) => Where(predicate).SingleOrDefault(); /// public object? SingleOrDefault(ref OperatorStringHandler predicate) => Where(ref predicate).SingleOrDefault(); /// /// Bypasses a specified number of elements in the set and then returns the remaining elements. /// /// The number of elements to skip before returning the remaining elements. /// A new that contains the elements that occur after the specified index in the current set. public SqlSet Skip(int count) { var ignoreBuffer = _buffer.Skip is null && _buffer.Take is null; var newBuffer = new SqlBuffer( Where: (ignoreBuffer) ? _buffer.Where : null, OrderBy: (ignoreBuffer) ? _buffer.OrderBy : null, Skip: count); var set = CreateBufferedSet(ignoreBuffer, newBuffer); return set; } /// /// Returns a specified number of contiguous elements from the start of the set. /// /// The number of elements to return. /// A new that contains the specified number of elements from the start of the current set. public SqlSet Take(int count) { var ignoreBuffer = _buffer.Take is null; var newBuffer = new SqlBuffer( Where: (ignoreBuffer) ? _buffer.Where : null, OrderBy: (ignoreBuffer) ? _buffer.OrderBy : null, Skip: (ignoreBuffer) ? _buffer.Skip : null, Take: count); var set = CreateBufferedSet(ignoreBuffer, newBuffer); return set; } /// /// Creates an array from the set. /// /// An array that contains the elements from the set. public object[] ToArray() => AsEnumerable().ToArray(); /// /// Creates a from the set. /// /// A that contains elements from the set. public List ToList() => AsEnumerable().ToList(); /// /// Filters the set based on a predicate. /// /// A SQL expression to test each row for a condition. /// A new that contains elements from the current set that satisfy the condition. public SqlSet Where(string predicate) { ArgumentNullException.ThrowIfNull(predicate); return Where(new SqlFragment(predicate)); } /// public SqlSet Where(ref OperatorStringHandler predicate) => Where(predicate.Fragment); SqlSet Where(ISqlFragment fragment) { var ignoreBuffer = _buffer.Where is null && _buffer.OrderBy is null && _buffer.Skip is null && _buffer.Take is null; var newBuffer = new SqlBuffer(Where: fragment); var set = CreateBufferedSet(ignoreBuffer, newBuffer); return set; } // Object Members /// [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object? obj) => base.Equals(obj); /// [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() => base.GetHashCode(); /// [EditorBrowsable(EditorBrowsableState.Never)] public new Type GetType() => base.GetType(); /// /// Returns the SQL query of the set. /// /// The SQL query of the set. public override string ToString() => GetDefiningQuery(clone: false).ToString(); internal record struct SqlBuffer(ISqlFragment? Where = null, ISqlFragment? OrderBy = null, int? Skip = null, int? Take = null) { public bool HasValue => Where is not null || OrderBy is not null || Skip is not null || Take is not null; } sealed class SqlFragment(string text, IList? parameters = null) : ISqlFragment { public IList ParameterValues { get; } = parameters ?? Array.Empty(); public override string ToString() => text; } sealed record class FetchClause() : SqlClause("FETCH", null); /// [EditorBrowsable(EditorBrowsableState.Never)] [InterpolatedStringHandler] public struct OperatorStringHandler { readonly SqlBuilder _builder; internal SqlBuilder Fragment => _builder; /// public OperatorStringHandler(int literalLength, int formattedCount) { _builder = new SqlBuilder(literalLength, formattedCount); } /// public void AppendLiteral(string value) => _builder.Buffer.Append(value); /// public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder.AppendPlaceholder(value, format); } } /// /// Represents an immutable, connected SQL query that maps to objects. /// This class cannot be instantiated, to get an instance use one of the /// or /// overloads. /// /// The type of objects to map the results to. /// public partial class SqlSet : SqlSet, ISqlSet, TResult> { readonly Func? _explicitMapper; internal SqlSet(SqlBuilder definingQuery, Database db) : base(definingQuery, typeof(TResult), db) { } internal SqlSet(SqlBuilder definingQuery, Func mapper, Database db) : base(definingQuery, typeof(TResult), db) { _explicitMapper = mapper; } internal SqlSet(string?[] fromSelect, Database db) : base(fromSelect, typeof(TResult), db) { } // These two SHOULD NOT pass TResult to base ctor // result type is copied from set private SqlSet(SqlSet set, SqlBuilder superQuery, SqlBuffer? buffer) : base((SqlSet)set, superQuery, default(Type), buffer) { _explicitMapper = set._explicitMapper; } private SqlSet(SqlSet set, string?[] fromSelect, SqlBuffer? buffer) : base((SqlSet)set, fromSelect, default(Type), buffer) { _explicitMapper = set._explicitMapper; } // These two SHOULD pass TResult to base ctor internal SqlSet(SqlSet set, SqlBuilder superQuery, Func? mapper, SqlBuffer? buffer) : base(set, superQuery, typeof(TResult), buffer) { if (mapper is not null) { _explicitMapper = mapper; } } internal SqlSet(SqlSet set, string?[] fromSelect, SqlBuffer? buffer) : base(set, fromSelect, typeof(TResult), buffer) { } private protected override SqlSet CreateSet(SqlBuilder superQuery, Type? resultType = null, SqlBuffer? buffer = null) { if (resultType is not null) { return base.CreateSet(superQuery, resultType, buffer); } return new SqlSet(this, superQuery, buffer); } private protected override SqlSet CreateSet(string?[] fromSelect, Type? resultType = null, SqlBuffer? buffer = null) { if (resultType is not null) { return base.CreateSet(fromSelect, resultType, buffer); } return new SqlSet(this, fromSelect, buffer); } private protected override IEnumerable Map(bool singleResult) { var query = GetDefiningQuery(clone: false); if (_explicitMapper is not null) { return _db.Map(query, _explicitMapper); } var results = default(IEnumerable); PocoMap(singleResult, query, ref results); return results ?? throw new InvalidOperationException("Cannot enumerate this set."); } partial void PocoMap(bool singleResult, SqlBuilder query, ref IEnumerable? results); // ISqlSet Members /// /// Gets all objects in the set. The query is deferred-executed. /// /// All objects in the set. public new IEnumerable AsEnumerable() => AsEnumerable(singleResult: false); IEnumerable AsEnumerable(bool singleResult) => Map(singleResult); /// /// Casts the elements of the set to the specified type. /// /// The type to cast the elements of the set to. /// A new that contains each element of the current set cast to the specified type. [EditorBrowsable(EditorBrowsableState.Never)] public new SqlSet Cast() => base.Cast(); /// [EditorBrowsable(EditorBrowsableState.Never)] public new SqlSet Cast(Type resultType) => base.Cast(resultType); /// public new TResult First() => Take(1).AsEnumerable(singleResult: true).First(); /// public new TResult First(string predicate) => Where(predicate).First(); /// public new TResult First(ref OperatorStringHandler predicate) => Where(ref predicate).First(); /// public new TResult? FirstOrDefault() => Take(1).AsEnumerable(singleResult: true).FirstOrDefault(); /// public new TResult? FirstOrDefault(string predicate) => Where(predicate).FirstOrDefault(); /// public new TResult? FirstOrDefault(ref OperatorStringHandler predicate) => Where(ref predicate).FirstOrDefault(); /// /// Returns an enumerator that iterates through the set. /// /// A for the set. public new IEnumerator GetEnumerator() => AsEnumerable().GetEnumerator(); /// /// A new whose elements are sorted according to . public new SqlSet OrderBy(string columnList) => (SqlSet)base.OrderBy(columnList); /// /// A new whose elements are sorted according to . public new SqlSet OrderBy(ref OperatorStringHandler columnList) => (SqlSet)base.OrderBy(ref columnList); /// public new TResult Single() => AsEnumerable(singleResult: true).Single(); /// public new TResult Single(string predicate) => Where(predicate).Single(); /// public new TResult Single(ref OperatorStringHandler predicate) => Where(ref predicate).Single(); /// public new TResult? SingleOrDefault() => AsEnumerable(singleResult: true).SingleOrDefault(); /// public new TResult? SingleOrDefault(string predicate) => Where(predicate).SingleOrDefault(); /// public new TResult? SingleOrDefault(ref OperatorStringHandler predicate) => Where(ref predicate).SingleOrDefault(); /// /// A new that contains the elements that occur after the specified index in the current set. public new SqlSet Skip(int count) => (SqlSet)base.Skip(count); /// /// A new that contains the specified number of elements from the start of the current set. public new SqlSet Take(int count) => (SqlSet)base.Take(count); /// public new TResult[] ToArray() => AsEnumerable().ToArray(); /// /// Creates a List<TResult> from the set. /// /// A List<TResult> that contains elements from the set. public new List ToList() => AsEnumerable().ToList(); /// /// A new that contains elements from the current set that satisfy the condition. public new SqlSet Where(string predicate) => (SqlSet)base.Where(predicate); /// /// A new that contains elements from the current set that satisfy the condition. public new SqlSet Where(ref OperatorStringHandler predicate) => (SqlSet)base.Where(ref predicate); } partial interface ISqlSet where TSqlSet : SqlSet { bool All(string predicate); bool All(ref SqlSet.OperatorStringHandler predicate); bool Any(); bool Any(string predicate); bool Any(ref SqlSet.OperatorStringHandler predicate); IEnumerable AsEnumerable(); SqlSet Cast(); SqlSet Cast(Type resultType); int Count(); int Count(string predicate); int Count(ref SqlSet.OperatorStringHandler predicate); TSource First(); TSource First(string predicate); TSource First(ref SqlSet.OperatorStringHandler predicate); TSource? FirstOrDefault(); TSource? FirstOrDefault(string predicate); TSource? FirstOrDefault(ref SqlSet.OperatorStringHandler predicate); IEnumerator GetEnumerator(); long LongCount(); long LongCount(string predicate); long LongCount(ref SqlSet.OperatorStringHandler predicate); TSqlSet OrderBy(string columnList); TSqlSet OrderBy(ref SqlSet.OperatorStringHandler columnList); SqlSet Select(string columnList); SqlSet Select(string columnList, Func mapper); SqlSet Select(ref SqlSet.OperatorStringHandler columnList); SqlSet Select(ref SqlSet.OperatorStringHandler columnList, Func mapper); SqlSet Select(string columnList); SqlSet Select(string columnList, Type resultType); SqlSet Select(ref SqlSet.OperatorStringHandler columnList); SqlSet Select(ref SqlSet.OperatorStringHandler columnList, Type resultType); TSource Single(); TSource Single(string predicate); TSource Single(ref SqlSet.OperatorStringHandler predicate); TSource? SingleOrDefault(); TSource? SingleOrDefault(string predicate); TSource? SingleOrDefault(ref SqlSet.OperatorStringHandler predicate); TSqlSet Skip(int count); TSqlSet Take(int count); TSource[] ToArray(); List ToList(); TSqlSet Where(string predicate); TSqlSet Where(ref SqlSet.OperatorStringHandler predicate); } ================================================ FILE: src/DbExtensions/SqlTable.Async.cs ================================================ // Copyright 2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace DbExtensions; using Metadata; #nullable enable partial class Database { /// /// This method is a shortcut for await db.Table(entity.GetType()).AddAsync(entity, cancellationToken). /// public async ValueTask AddAsync(object entity, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entity); await Table(entity.GetType()) .AddAsync(entity, cancellationToken) .ConfigureAwait(false); } /// /// This method is a shortcut for await db.Table(entity.GetType()).UpdateAsync(entity, cancellationToken). /// public async ValueTask UpdateAsync(object entity, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entity); await Table(entity.GetType()) .UpdateAsync(entity, cancellationToken) .ConfigureAwait(false); } /// /// This method is a shortcut for await db.Table(entity.GetType()).UpdateAsync(entity, originalId, cancellationToken). /// public async ValueTask UpdateAsync(object entity, object? originalId, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entity); await Table(entity.GetType()) .UpdateAsync(entity, originalId, cancellationToken) .ConfigureAwait(false); } /// /// This method is a shortcut for await db.Table(entity.GetType()).RemoveAsync(entity, cancellationToken). /// public async ValueTask RemoveAsync(object entity, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entity); return await Table(entity.GetType()) .RemoveAsync(entity, cancellationToken) .ConfigureAwait(false); } } partial class SqlTable { /// public ValueTask AddAsync(object entity, CancellationToken cancellationToken = default) => _table.AddAsync(entity, cancellationToken); /// public ValueTask AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) => _table.AddRangeAsync(entities, cancellationToken); /// public ValueTask AddRangeAsync(params object[] entities) => _table.AddRangeAsync(entities); /// public ValueTask RemoveAsync(object entity, CancellationToken cancellationToken = default) => _table.RemoveAsync(entity, cancellationToken); /// public ValueTask RemoveKeyAsync(object id, CancellationToken cancellationToken = default) => _table.RemoveKeyAsync(id, cancellationToken); /// public ValueTask RemoveRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) => _table.RemoveRangeAsync(entities, cancellationToken); /// public ValueTask RemoveRangeAsync(params object[] entities) => _table.RemoveRangeAsync(entities); /// public ValueTask RefreshAsync(object entity, CancellationToken cancellationToken = default) => _table.RefreshAsync(entity, cancellationToken); /// public ValueTask UpdateAsync(object entity, CancellationToken cancellationToken = default) => _table.UpdateAsync(entity, cancellationToken); /// public ValueTask UpdateAsync(object entity, object? originalId, CancellationToken cancellationToken = default) => _table.UpdateAsync(entity, originalId, cancellationToken); /// public ValueTask UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) => _table.UpdateRangeAsync(entities, cancellationToken); /// public ValueTask UpdateRangeAsync(params object[] entities) => _table.UpdateRangeAsync(entities); } partial class SqlTable { /// /// public async ValueTask AddAsync(TEntity entity, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entity); var idMember = _metaType.DBGeneratedIdentityMember; var outputIdMember = idMember is not null && _db.Configuration.SqlDialect is SqlDialect.TSql; var syncMembers = _metaType.PersistentDataMembers .Where(m => m.AutoSync is AutoSync.Always or AutoSync.OnInsert && m != idMember) .ToArray(); var insertSql = BuildInsertStatementForEntity(entity, outputIdMember); var id = default(object); var tx = await _db.EnsureInTransactionAsync(cancellationToken) .ConfigureAwait(false); await using var txDisp = tx.ConfigureAwait(false); if (outputIdMember) { // this block emulates Database.Execute() var cmd = _db.CreateCommand(insertSql); try { id = await cmd.ExecuteScalarAsync(cancellationToken) .ConfigureAwait(false); } catch { _db.Trace(cmd, error: true); throw; } _db.Trace(cmd); } else { await _db.ExecuteAsync(insertSql, affect: 1, exact: true, cancellationToken) .ConfigureAwait(false); if (idMember is not null) { id = await _db.LastInsertIdAsync(cancellationToken) .ConfigureAwait(false); } } if (idMember is not null) { var convertedId = Convert.ChangeType(id, idMember.Type, CultureInfo.InvariantCulture); var entityObj = (object)entity; idMember.MemberAccessor.SetBoxedValue(ref entityObj, convertedId); } if (syncMembers.Length > 0 && _metaType.IsEntity) { await RefreshAsync(entity, syncMembers, cancellationToken) .ConfigureAwait(false); } await InsertDescendantsAsync(entity, cancellationToken) .ConfigureAwait(false); await tx.CommitAsync(cancellationToken) .ConfigureAwait(false); } async ValueTask InsertDescendantsAsync(TEntity entity, CancellationToken cancellationToken) { await InsertOneToOneAsync(entity, cancellationToken) .ConfigureAwait(false); await InsertOneToManyAsync(entity, cancellationToken) .ConfigureAwait(false); } async ValueTask InsertOneToOneAsync(TEntity entity, CancellationToken cancellationToken) { foreach (var assoc in _metaType.Associations .Where(a => !a.IsMany && a.ThisKeyIsPrimaryKey && a.OtherKeyIsPrimaryKey)) { var child = assoc.ThisMember.MemberAccessor.GetBoxedValue(entity); if (child is null) { continue; } for (int j = 0; j < assoc.ThisKey.Count; j++) { var thisKey = assoc.ThisKey[j]; var otherKey = assoc.OtherKey[j]; var thisKeyVal = thisKey.MemberAccessor.GetBoxedValue(entity); otherKey.MemberAccessor.SetBoxedValue(ref child, thisKeyVal); } var otherTable = _db.Table(assoc.OtherType); await otherTable.AddAsync(child, cancellationToken) .ConfigureAwait(false); } } async ValueTask InsertOneToManyAsync(TEntity entity, CancellationToken cancellationToken) { foreach (var assoc in _metaType.Associations.Where(a => a.IsMany)) { var many = ((IEnumerable)assoc.ThisMember.MemberAccessor.GetBoxedValue(entity) ?? []) .Where(o => o is not null) .ToArray(); if (many.Length == 0) { continue; } foreach (var child in many) { for (int k = 0; k < assoc.ThisKey.Count; k++) { var thisKey = assoc.ThisKey[k]; var otherKey = assoc.OtherKey[k]; var thisKeyVal = thisKey.MemberAccessor.GetBoxedValue(entity); var c = child; otherKey.MemberAccessor.SetBoxedValue(ref c, thisKeyVal); } } var otherTable = _db.Table(assoc.OtherType); await otherTable.AddRangeAsync(many, cancellationToken) .ConfigureAwait(false); } } /// /// public async ValueTask AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entities); await AddRangeAsync(entities as TEntity[] ?? entities.ToArray(), cancellationToken) .ConfigureAwait(false); } /// public ValueTask AddRangeAsync(params TEntity[] entities) => AddRangeAsync(entities, default(CancellationToken)); async ValueTask AddRangeAsync(TEntity[] entities, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(entities); entities = entities.Where(o => o is not null) .ToArray(); if (entities.Length == 0) { return; } if (entities.Length == 1) { await AddAsync(entities[0], cancellationToken) .ConfigureAwait(false); return; } var syncMembers = _metaType.PersistentDataMembers .Where(m => m.AutoSync is AutoSync.Always or AutoSync.OnInsert) .ToArray(); var batch = syncMembers.Length == 0 && _db.Configuration.EnableBatchCommands; if (batch) { var batchInsert = SqlBuilder.JoinSql( ";" + Environment.NewLine, entities.Select(e => BuildInsertStatementForEntity(e))); var tx = await _db.EnsureInTransactionAsync(cancellationToken) .ConfigureAwait(false); await using var txDisp = tx.ConfigureAwait(false); await _db.ExecuteAsync(batchInsert, affect: entities.Length, exact: true, cancellationToken) .ConfigureAwait(false); foreach (var e in entities) { await InsertDescendantsAsync(e, cancellationToken) .ConfigureAwait(false); } await tx.CommitAsync(cancellationToken) .ConfigureAwait(false); } else { var tx = await _db.EnsureInTransactionAsync(cancellationToken) .ConfigureAwait(false); await using var txDisp = tx.ConfigureAwait(false); foreach (var e in entities) { await AddAsync(e, cancellationToken) .ConfigureAwait(false); } await tx.CommitAsync(cancellationToken) .ConfigureAwait(false); } } /// /// public async ValueTask RemoveAsync(TEntity entity, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entity); var deleteSql = BuildDeleteStatementForEntity(entity); var usingVersion = _db.Configuration.UseVersionMember && _metaType.VersionMember is not null; return await _db.ExecuteAsync(deleteSql, affect: 1, exact: usingVersion, cancellationToken) .ConfigureAwait(false) == 1; } /// /// public async ValueTask RemoveKeyAsync(object id, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(id); var deleteSql = BuildDeleteStatementForKey(id); return await _db.ExecuteAsync(deleteSql, affect: 1, cancellationToken: cancellationToken) .ConfigureAwait(false) == 1; } /// /// public async ValueTask RemoveRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entities); await RemoveRangeAsync(entities as TEntity[] ?? entities.ToArray(), cancellationToken) .ConfigureAwait(false); } /// public ValueTask RemoveRangeAsync(params TEntity[] entities) => RemoveRangeAsync(entities, default(CancellationToken)); async ValueTask RemoveRangeAsync(TEntity[] entities, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(entities); entities = entities.Where(o => o is not null) .ToArray(); if (entities.Length == 0) { return; } if (entities.Length == 1) { await RemoveAsync(entities[0], cancellationToken) .ConfigureAwait(false); return; } EnsureEntityType(); var usingVersion = _db.Configuration.UseVersionMember && _metaType.VersionMember is not null; var singleStatement = _metaType.IdentityMembers.Count == 1 && !usingVersion; var batch = _db.Configuration.EnableBatchCommands; if (singleStatement) { var idMember = _metaType.IdentityMembers[0]; var ids = entities.Select(e => idMember.GetValueForDatabase(e)) .ToArray(); var sql = BuildDeleteStatement() .WHERE(String.Empty); var sb = sql.Buffer; _db.QuoteIdentifier(sb, idMember.MappedName); sb.Append(" IN ("); for (int i = 0; i < ids.Length; i++) { if (i > 0) { sb.Append(',') .Append(' '); } sb.Append('{') .Append(sql.ParameterValues.Count) .Append('}'); sql.ParameterValues.Add(ids[i]); } sb.Append(')'); await _db.ExecuteAsync(sql, affect: entities.Length, cancellationToken: cancellationToken) .ConfigureAwait(false); } else if (batch) { var batchDelete = SqlBuilder.JoinSql( ";" + Environment.NewLine, entities.Select(e => BuildDeleteStatementForEntity(e))); await _db.ExecuteAsync(batchDelete, affect: entities.Length, exact: usingVersion, cancellationToken) .ConfigureAwait(false); } else { var tx = await _db.EnsureInTransactionAsync(cancellationToken) .ConfigureAwait(false); await using var txDisp = tx.ConfigureAwait(false); foreach (var e in entities) { await RemoveAsync(e, cancellationToken) .ConfigureAwait(false); } await tx.CommitAsync(cancellationToken) .ConfigureAwait(false); } } /// /// public ValueTask RefreshAsync(TEntity entity, CancellationToken cancellationToken = default) => RefreshAsync(entity, null, cancellationToken); async ValueTask RefreshAsync(TEntity entity, IEnumerable? refreshMembers, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(entity); EnsureEntityType(); var query = BuildSelectStatement(refreshMembers); query.WHERE(_db.BuildPredicateFragment(entity, _metaType.IdentityMembers, query.ParameterValues)); var mapper = _db.CreatePocoMapper(_metaType.Type); var entityObj = (object)entity; _ = await _db.AsyncMap(query, r => { mapper.PocoLoad(entityObj, r); return null; }).SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } /// /// public ValueTask UpdateAsync(TEntity entity, CancellationToken cancellationToken = default) => UpdateAsync(entity, null, cancellationToken); /// /// public async ValueTask UpdateAsync(TEntity entity, object? originalId, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entity); var updateSql = BuildUpdateStatementForEntity(entity, originalId); var syncMembers = _metaType.PersistentDataMembers .Where(m => m.AutoSync is AutoSync.Always or AutoSync.OnUpdate) .ToArray(); await using var conn = (await _db.EnsureConnectionOpenAsync(cancellationToken) .ConfigureAwait(false)) .ConfigureAwait(false); await _db.ExecuteAsync(updateSql, affect: 1, exact: true, cancellationToken) .ConfigureAwait(false); if (syncMembers.Length > 0) { await RefreshAsync(entity, syncMembers, cancellationToken) .ConfigureAwait(false); } } /// /// public async ValueTask UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entities); await UpdateRangeAsync(entities as TEntity[] ?? entities.ToArray(), cancellationToken) .ConfigureAwait(false); } /// /// public ValueTask UpdateRangeAsync(params TEntity[] entities) => UpdateRangeAsync(entities, default(CancellationToken)); async ValueTask UpdateRangeAsync(TEntity[] entities, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(entities); entities = entities.Where(o => o is not null) .ToArray(); if (entities.Length == 0) { return; } if (entities.Length == 1) { await UpdateAsync(entities[0], cancellationToken) .ConfigureAwait(false); return; } EnsureEntityType(); var syncMembers = _metaType.PersistentDataMembers .Where(m => m.AutoSync is AutoSync.Always or AutoSync.OnUpdate) .ToArray(); var batch = syncMembers.Length == 0 && _db.Configuration.EnableBatchCommands; if (batch) { var batchUpdate = SqlBuilder.JoinSql( ";" + Environment.NewLine, entities.Select(e => BuildUpdateStatementForEntity(e))); await _db.ExecuteAsync(batchUpdate, affect: entities.Length, exact: true, cancellationToken) .ConfigureAwait(false); } else { var tx = await _db.EnsureInTransactionAsync(cancellationToken) .ConfigureAwait(false); await using var txDisp = tx.ConfigureAwait(false); foreach (var e in entities) { await UpdateAsync(e, cancellationToken) .ConfigureAwait(false); } await tx.CommitAsync(cancellationToken) .ConfigureAwait(false); } } // ISqlTable Members ValueTask ISqlTable.AddAsync(object entity, CancellationToken cancellationToken) => AddAsync((TEntity)entity, cancellationToken); ValueTask ISqlTable.AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken) => AddRangeAsync(entities.Cast(), cancellationToken); ValueTask ISqlTable.AddRangeAsync(params object[] entities) => AddRangeAsync(entities.Cast()); ValueTask ISqlTable.RemoveAsync(object entity, CancellationToken cancellationToken) => RemoveAsync((TEntity)entity, cancellationToken); ValueTask ISqlTable.RemoveKeyAsync(object id, CancellationToken cancellationToken) => RemoveKeyAsync(id, cancellationToken); ValueTask ISqlTable.RemoveRangeAsync(IEnumerable entities, CancellationToken cancellationToken) => RemoveRangeAsync(entities.Cast(), cancellationToken); ValueTask ISqlTable.RemoveRangeAsync(params object[] entities) => RemoveRangeAsync(entities.Cast()); ValueTask ISqlTable.RefreshAsync(object entity, CancellationToken cancellationToken) => RefreshAsync((TEntity)entity, cancellationToken); ValueTask ISqlTable.UpdateAsync(object entity, CancellationToken cancellationToken) => UpdateAsync((TEntity)entity, cancellationToken); ValueTask ISqlTable.UpdateAsync(object entity, object? originalId, CancellationToken cancellationToken) => UpdateAsync((TEntity)entity, originalId, cancellationToken); ValueTask ISqlTable.UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken) => UpdateRangeAsync(entities.Cast(), cancellationToken); ValueTask ISqlTable.UpdateRangeAsync(params object[] entities) => UpdateRangeAsync(entities.Cast()); } partial interface ISqlTable { ValueTask AddAsync(object entity, CancellationToken cancellationToken); ValueTask AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken); ValueTask AddRangeAsync(params object[] entities); ValueTask RemoveAsync(object entity, CancellationToken cancellationToken); ValueTask RemoveKeyAsync(object id, CancellationToken cancellationToken); ValueTask RemoveRangeAsync(IEnumerable entities, CancellationToken cancellationToken); ValueTask RemoveRangeAsync(params object[] entities); ValueTask RefreshAsync(object entity, CancellationToken cancellationToken); ValueTask UpdateAsync(object entity, CancellationToken cancellationToken); ValueTask UpdateAsync(object entity, object? originalId, CancellationToken cancellationToken); ValueTask UpdateRangeAsync(IEnumerable entities, CancellationToken cancellationToken); ValueTask UpdateRangeAsync(params object[] entities); } ================================================ FILE: src/DbExtensions/SqlTable.SqlSet.cs ================================================ // Copyright 2012-2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; namespace DbExtensions; using Metadata; #nullable enable partial class Database { /// /// The type of the entity. /// This method is a shortcut for db.Table<TEntity>().Find(id). /// public TEntity? Find(object id) where TEntity : class => Table().Find(id); } partial class SqlSet { MetaType EnsureAnnotatedType() { if (_resultType is null) { throw new InvalidOperationException("The operation is not supported on untyped sets."); } var metaType = _db.Configuration.GetMetaType(_resultType) ?? throw new InvalidOperationException($"Mapping information was not found for '{_resultType.FullName}'."); return metaType; } MetaType EnsureEntityType(int maxIdMembers = -1) { var metaType = EnsureAnnotatedType(); SqlTable.EnsureEntityType(metaType); if (maxIdMembers > 0 && metaType.IdentityMembers.Count > maxIdMembers) { throw new InvalidOperationException("The operation is not supported for entities with more than one identity member."); } return metaType; } /// /// Checks the existance of the , using the primary key value. /// /// The entity whose existance is to be checked. /// true if the primary key value exists in the database; otherwise, false. /// This method can only be used on sets where the result type is an annotated class. public bool Contains(object entity) { ArgumentNullException.ThrowIfNull(entity); var (fragment, columnList) = ContainsEntityImplParams(entity); return Where(fragment) .Select(columnList) .Any(); } (ISqlFragment, string) ContainsEntityImplParams(object entity) { var metaType = EnsureEntityType(); var predicateMembers = metaType.PersistentDataMembers .Where(m => m.IsPrimaryKey || (m.IsVersion && _db.Configuration.UseVersionMember)) .ToArray(); var predicateValues = predicateMembers.ToDictionary( m => m.MappedName, m => m.GetValueForDatabase(entity)); return ContainsImplParams(predicateMembers, predicateValues); } /// /// Checks the existance of an entity whose primary matches the parameter. /// /// The primary key value. /// true if the primary key value exists in the database; otherwise, false. /// This method can only be used on sets where the result type is an annotated class. public bool ContainsKey(object id) { ArgumentNullException.ThrowIfNull(id); var (fragment, columnList) = ContainsKeyImplParams(id); return Where(fragment) .Select(columnList) .Any(); } (ISqlFragment, string) ContainsKeyImplParams(object id) { var metaType = EnsureEntityType(maxIdMembers: 1); var idMember = metaType.IdentityMembers[0]; var predicateMembers = new[] { idMember }; var predicateValues = new KeyValuePair[] { new(idMember.MappedName, idMember.ConvertValueForDatabase(id)) }; return ContainsImplParams(predicateMembers, predicateValues); } (ISqlFragment, string) ContainsImplParams(MetaDataMember[] predicateMembers, IEnumerable> predicateValues) { var metaType = predicateMembers[0].DeclaringType; var predicateParams = new List(predicateMembers.Length); var fragment = new SqlFragment(_db.BuildPredicateFragment(predicateValues, predicateParams), predicateParams); var columnList = _db.SelectBody(metaType, predicateMembers); return (fragment, columnList); } /// /// Gets the entity whose primary key matches the parameter. /// /// The primary key value. /// /// The entity whose primary key matches the parameter, /// or null if the does not exist. /// /// This method can only be used on sets where the result type is an annotated class. public object? Find(object id) => FindImpl(id).SingleOrDefault(); private protected SqlSet FindImpl(object id) { ArgumentNullException.ThrowIfNull(id); var metaType = EnsureEntityType(maxIdMembers: 1); var idMember = metaType.IdentityMembers[0]; var predicateValues = new KeyValuePair[] { new(idMember.MappedName, idMember.ConvertValueForDatabase(id)) }; var parameters = new List(predicateValues.Length); var fragment = new SqlFragment(_db.BuildPredicateFragment(predicateValues, parameters), parameters); return Where(fragment); } /// /// Specifies the related objects to include in the query results. /// /// Dot-separated list of related objects to return in the query results. /// A new with the defined query path. /// This method can only be used on sets where the result type is an annotated class. public SqlSet Include(string path) { ArgumentNullException.ThrowIfNull(path); var metaType = EnsureAnnotatedType(); var parts = IncludePathSplit(path); const string leftAlias = "dbex_l"; const string rightAlias = "dbex_r"; static string rAliasFn(int i) => rightAlias + (i + 1); var query = new SqlBuilder() .SELECT(String.Empty); var sb = query.Buffer; _db.QuoteIdentifier(sb, leftAlias); sb.Append(".*"); var currentType = metaType; var associations = new List(parts.Length); for (int i = 0; i < parts.Length; i++) { var p = parts[i]; var rAlias = rAliasFn(i); var member = currentType.PersistentDataMembers .SingleOrDefault(m => m.Name == p) ?? throw new ArgumentException($"Couldn't find '{p}' on '{currentType.Type.FullName}'.", nameof(path)); if (!member.IsAssociation) { throw new ArgumentException($"'{p}' is not an association property.", nameof(path)); } var association = member.Association; if (association.IsMany) { throw new ArgumentException($"Use the IncludeMany method to load collections ('{path}').", nameof(path)); } associations.Add(association); foreach (var m in association.OtherType.PersistentDataMembers .Where(m => !m.IsAssociation)) { query.SELECT(String.Empty); _db.QuoteIdentifier(sb, rAlias); sb.Append('.'); _db.QuoteIdentifier(sb, m.MappedName); sb.Append(" AS "); foreach (var a in associations) { sb.Append(a.ThisMember.Name) .Append('$'); } sb.Append(m.Name); } currentType = association.OtherType; } query.FROM(GetDefiningQuery(clone: false), _db.QuoteIdentifier(leftAlias)); for (int i = 0; i < associations.Count; i++) { var association = associations[i]; var lAlias = (i == 0) ? leftAlias : rAliasFn(i - 1); var rAlias = rAliasFn(i); query.LEFT_JOIN(String.Empty); _db.QuoteIdentifier(sb, association.OtherType.Table.TableName); sb.Append(' '); _db.QuoteIdentifier(sb, rAlias); sb.Append(" ON ("); for (int j = 0; j < association.ThisKey.Count; j++) { if (j > 0) { sb.Append(" AND "); } var thisMember = association.ThisKey[j]; var otherMember = association.OtherKey[j]; _db.QuoteIdentifier(sb, lAlias); sb.Append('.'); _db.QuoteIdentifier(sb, (i > 0) ? thisMember.MappedName : thisMember.Name); sb.Append(" = "); _db.QuoteIdentifier(sb, rAlias); sb.Append('.'); _db.QuoteIdentifier(sb, otherMember.MappedName); } sb.Append(')'); } var newSet = CreateSet(query); return newSet; } /// /// Specifies which collections to include in the query results. /// /// Dot-separated list of one or more related objects that ends with the collection to load. /// A function to customize how the collection is loaded. /// A new . /// This method can only be used on sets where the result type is an annotated class. public SqlSet IncludeMany(string path, Func? manySetup = null) { ArgumentNullException.ThrowIfNull(path); var metaType = EnsureAnnotatedType(); var parts = IncludePathSplit(path); var currentType = metaType; var manyAssoc = default(MetaAssociation); for (int i = 0; i < parts.Length; i++) { var p = parts[i]; var member = currentType.PersistentDataMembers .SingleOrDefault(m => m.Name == p) ?? throw new ArgumentException($"Couldn't find '{p}' on '{currentType.Type.FullName}'.", nameof(path)); if (!member.IsAssociation) { throw new ArgumentException($"'{p}' is not an association property.", nameof(path)); } var association = member.Association; if (i == parts.Length - 1) { if (association.IsMany) { manyAssoc = association; break; } throw new ArgumentException( $"The last segment of the path must refer to a collection ('{path}').", nameof(path)); } else if (association.IsMany) { throw new ArgumentException( $"Only the last segment of the path can refer to a collection ('{path}'). " + "Use the elementPath parameter to include a path in the collection.", nameof(path)); } currentType = association.OtherType; } Debug.Assert(manyAssoc is not null); var manySource = (SqlSet)_db.Table(manyAssoc.OtherType); var newSet = Clone(); newSet.AddManyInclude(parts, container => manyAssoc.LoadCollection(container, manyFetch(container))); return newSet; IEnumerable manyFetch(object container) { var predicateValues = manyAssoc.OtherKey.Select((p, i) => new KeyValuePair(p.MappedName, manyAssoc.ThisKey[i].GetValueForDatabase(container))); var parameters = new List(manyAssoc.OtherKey.Count); var whereFragment = new SqlFragment(manySource.Database.BuildPredicateFragment(predicateValues, parameters), parameters); manySource = manySource .Where(whereFragment); if (manySetup is not null) { manySource = manySetup.Invoke(manySource); } return manySource.AsEnumerable(); } } static string[] IncludePathSplit(string path) { var pathParts = path.Split('.', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); if (pathParts.Length == 0) { throw new ArgumentException("Path is empty.", nameof(path)); } return pathParts; } } partial class SqlSet { /// [EditorBrowsable(EditorBrowsableState.Never)] public new bool Contains(object entity) => Contains((TResult)entity); /// public bool Contains(TResult entity) => base.Contains(entity!); /// public new TResult? Find(object id) => ((SqlSet)FindImpl(id)).SingleOrDefault(); /// /// A new with the defined query path. public new SqlSet Include(string path) => (SqlSet)base.Include(path); /// /// Lambda expression that returns the deepest related object to return in the query results. /// This argument is compiler generated. public SqlSet Include(Func path, [CallerArgumentExpression(nameof(path))] string pathExpr = "") { ArgumentNullException.ThrowIfNull(path); ArgumentException.ThrowIfNullOrEmpty(pathExpr); var pathStr = IncludeLambdaPath(pathExpr); return Include(pathStr); } /// /// A new . public new SqlSet IncludeMany(string path, Func? manySetup = null) => (SqlSet)base.IncludeMany(path, manySetup); /// /// The type of objects the collection holds. /// Lambda expression that returns the collection to load. /// This argument is compiler generated. public SqlSet IncludeMany( Func?> path, Func, SqlSet>? manySetup = null, [CallerArgumentExpression(nameof(path))] string pathExpr = "") { ArgumentNullException.ThrowIfNull(path); ArgumentException.ThrowIfNullOrEmpty(pathExpr); var pathStr = IncludeLambdaPath(pathExpr); return IncludeMany(pathStr, (manySetup != null) ? p => manySetup.Invoke(p.Cast()) : null); } static string IncludeLambdaPath(string pathExpr) { var arrowIndex = pathExpr.IndexOf("=>"); if (arrowIndex == -1) { throw new ArgumentException("A lambda expression is expected.", nameof(pathExpr)); } var firstDot = pathExpr.IndexOf('.', arrowIndex); if (firstDot == -1) { throw new ArgumentException("Path is empty.", nameof(pathExpr)); } return pathExpr .Substring(firstDot + 1); } } // Async partial class Database { /// /// The type of the entity. /// This method is a shortcut for await db.Table<TEntity>().FindAsync(id, cancellationToken). public async ValueTask FindAsync(object id, CancellationToken cancellationToken = default) where TEntity : class { return await Table() .FindAsync(id, cancellationToken) .ConfigureAwait(false); } } partial class SqlSet { /// /// public async ValueTask ContainsAsync(object entity, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(entity); var (fragment, columnList) = ContainsEntityImplParams(entity); return await Where(fragment) .Select(columnList) .AnyAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask ContainsKeyAsync(object id, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(id); var (fragment, columnList) = ContainsKeyImplParams(id); return await Where(fragment) .Select(columnList) .AnyAsync(cancellationToken) .ConfigureAwait(false); } /// /// public async ValueTask FindAsync(object id, CancellationToken cancellationToken = default) { return await FindImpl(id) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } } partial class SqlSet { /// [EditorBrowsable(EditorBrowsableState.Never)] public new ValueTask ContainsAsync(object entity, CancellationToken cancellationToken = default) => ContainsAsync((TResult)entity, cancellationToken); /// public ValueTask ContainsAsync(TResult entity, CancellationToken cancellationToken = default) => base.ContainsAsync(entity!, cancellationToken); /// public new async ValueTask FindAsync(object id, CancellationToken cancellationToken = default) { return await ((SqlSet)FindImpl(id)) .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } } ================================================ FILE: src/DbExtensions/SqlTable.cs ================================================ // Copyright 2012-2025 Max Toro Q. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; namespace DbExtensions; using Metadata; #nullable enable partial class Database { static readonly MethodInfo _tableMethod = typeof(Database) .GetMethod(nameof(Table), 1, Type.EmptyTypes)!; static readonly MappingSource _mappingSource = new AttributeMappingSource(); readonly Dictionary _tables = new(); readonly Dictionary _genericTables = new(); partial void Initialize2(string providerInvariantName) { this.Configuration.SetModel(() => _mappingSource.GetModel(GetType())); Initialize3(providerInvariantName); } partial void Initialize3(string providerInvariantName); /// /// Returns the instance for the specified . /// /// The type of the entity. /// The instance for . public SqlTable Table() where TEntity : class { var metaType = this.Configuration.GetMetaType(typeof(TEntity)); ref var table = ref CollectionsMarshal.GetValueRefOrAddDefault(_genericTables, metaType, out var exists); if (!exists) { table = new SqlTable(this, metaType); } return (SqlTable)table!; } /// /// Returns the instance for the specified . /// /// The type of the entity. /// The instance for . public SqlTable Table(Type entityType) { ArgumentNullException.ThrowIfNull(entityType); return Table(this.Configuration.GetMetaType(entityType)); } internal SqlTable Table(MetaType metaType) { ref var table = ref CollectionsMarshal.GetValueRefOrAddDefault(_tables, metaType, out var exists); if (!exists) { var genericTable = (ISqlTable)_tableMethod .MakeGenericMethod(metaType.Type) .Invoke(this, null)!; table = new SqlTable(this, metaType, genericTable); } return table!; } /// /// This method is a shortcut for db.Table(entity.GetType()).Add(entity). /// public void Add(object entity) { ArgumentNullException.ThrowIfNull(entity); Table(entity.GetType()) .Add(entity); } /// /// This method is a shortcut for db.Table(entity.GetType()).Update(entity). /// public void Update(object entity) { ArgumentNullException.ThrowIfNull(entity); Table(entity.GetType()) .Update(entity); } /// /// This method is a shortcut for db.Table(entity.GetType()).Update(entity, originalId). /// public void Update(object entity, object? originalId) { ArgumentNullException.ThrowIfNull(entity); Table(entity.GetType()) .Update(entity, originalId); } /// /// This method is a shortcut for db.Table(entity.GetType()).Remove(entity). /// public bool Remove(object entity) { ArgumentNullException.ThrowIfNull(entity); return Table(entity.GetType()) .Remove(entity); } internal string BuildPredicateFragment( object entity, IEnumerable predicateMembers, ICollection parametersBuffer, Func? getValueFn = null) { var predicateValues = predicateMembers.Select(m => new KeyValuePair( m.MappedName, (getValueFn is not null) ? getValueFn.Invoke(m) : m.GetValueForDatabase(entity))); return BuildPredicateFragment(predicateValues, parametersBuffer); } internal string BuildPredicateFragment(IEnumerable> predicateValues, ICollection parametersBuffer) { //if (predicateValues is null || predicateValues.Count == 0) throw new ArgumentException("predicateValues cannot be empty", nameof(predicateValues)); ArgumentNullException.ThrowIfNull(parametersBuffer); var sb = new StringBuilder(); foreach (var item in predicateValues) { if (sb.Length > 0) { sb.Append(" AND "); } QuoteIdentifier(sb, item.Key); if (item.Value is null) { sb.Append(" IS NULL"); } else { sb.Append(" = {") .Append(parametersBuffer.Count) .Append('}'); parametersBuffer.Add(item.Value); } } return sb.ToString(); } internal string SelectBody(MetaType metaType, IEnumerable? selectMembers) { var sb = new StringBuilder(); SelectBody(sb, metaType, selectMembers, null); return sb.ToString(); } internal void SelectBody(StringBuilder sb, MetaType metaType, IEnumerable? selectMembers, string? tableAlias) { selectMembers ??= metaType.PersistentDataMembers.Where(m => !m.IsAssociation); var appendAlias = !String.IsNullOrEmpty(tableAlias); var i = -1; foreach (var member in selectMembers) { i++; var mappedName = member.MappedName; var memberName = member.QueryPath; var columnAlias = !String.Equals(mappedName, memberName, StringComparison.Ordinal) ? memberName : null; if (i > 0) { sb.Append(',') .Append(' '); } if (appendAlias) { QuoteIdentifier(sb, tableAlias!); sb.Append('.'); } QuoteIdentifier(sb, mappedName); if (columnAlias is not null) { sb.Append(" AS "); QuoteIdentifier(sb, columnAlias); } } } internal string FromBody(MetaType metaType) { if (metaType.Table is null) throw new InvalidOperationException("metaType.Table cannot be null."); return QuoteIdentifier(metaType.Table.TableName); } } partial class DatabaseConfiguration { Lazy _model; MetaTableConfiguration _defaultMetaTableConfig; /// /// Gets the on which the mapping is based. /// internal MetaModel Model => _model.Value; /// /// true to include version column check in SQL statements' predicates; otherwise, false. The default is true. /// public bool UseVersionMember { get; set; } = true; /// /// true to execute batch commands when possible; otherwise, false. The default is true. /// /// /// This setting affects the behavior of , /// and . /// public bool EnableBatchCommands { get; set; } = true; /// /// The default separator to use when mapping complex properties. /// The default value is null, which means no separator is used, unless an explicit separator /// is specified on . /// public string? DefaultComplexPropertySeparator { get; set; } internal MetaTableConfiguration DefaultMetaTableConfig => _defaultMetaTableConfig ??= new MetaTableConfiguration { DefaultComplexPropertySeparator = this.DefaultComplexPropertySeparator }; internal void SetModel(Func modelFn) { _model = new Lazy(modelFn); } internal MetaType GetMetaType(Type type) => this.Model.GetMetaType(type, this.DefaultMetaTableConfig); } /// /// A non-generic version of which can be used when the type of the entity is not known at build time. /// This class cannot be instantiated, to get an instance use the method. /// [DebuggerDisplay($"{{{nameof(_metaType)}.{nameof(_metaType.Name)}}}")] public sealed partial class SqlTable : SqlSet, ISqlTable { // table is the SqlTable instance for metaType // SqlTable is only a wrapper on SqlTable readonly ISqlTable _table; readonly MetaType _metaType; /// public string Name => _metaType.Table.TableName; internal SqlTable(Database db, MetaType metaType, ISqlTable table) : base([db.FromBody(metaType), db.SelectBody(metaType, null)], metaType.Type, db) { _table = table; _metaType = metaType; } /// /// Casts the current to the generic instance. /// /// The type of the entity. /// The instance for . /// The specified is not valid for this instance. public new SqlTable Cast() where TEntity : class { if (typeof(TEntity) != _metaType.Type) { throw new InvalidOperationException("The specified type parameter is not valid for this instance."); } return (SqlTable)_table; } /// [EditorBrowsable(EditorBrowsableState.Never)] public new SqlSet Cast(Type resultType) => base.Cast(resultType); internal static void EnsureEntityType(MetaType metaType) { if (!metaType.IsEntity) { throw new InvalidOperationException($"The operation is not available for non-entity types ('{metaType.Type.FullName}')."); } } // ISqlTable Members: these methods just call the same method on _table /// public void Add(object entity) => _table.Add(entity); /// public void AddRange(IEnumerable entities) => _table.AddRange(entities); /// public void AddRange(params object[] entities) => _table.AddRange(entities); /// public void Update(object entity) => _table.Update(entity); /// public void Update(object entity, object? originalId) => _table.Update(entity, originalId); /// public void UpdateRange(IEnumerable entities) => _table.UpdateRange(entities); /// public void UpdateRange(params object[] entities) => _table.UpdateRange(entities); /// public bool Remove(object entity) => _table.Remove(entity); /// public bool RemoveKey(object id) => _table.RemoveKey(id); /// public void RemoveRange(IEnumerable entities) => _table.RemoveRange(entities); /// public void RemoveRange(params object[] entities) => _table.RemoveRange(entities); /// public void Refresh(object entity) => _table.Refresh(entity); } /// /// A that provides CRUD (Create, Read, Update, Delete) /// operations for annotated classes. /// This class cannot be instantiated, to get an instance use the method. /// /// The type of the entity. [DebuggerDisplay($"{{{nameof(_metaType)}.{nameof(_metaType.Name)}}}")] public sealed partial class SqlTable : SqlSet, ISqlTable where TEntity : class { readonly MetaType _metaType; /// /// Gets the name of the table. /// public string Name => _metaType.Table.TableName; internal SqlTable(Database db, MetaType metaType) : base([db.FromBody(metaType), db.SelectBody(metaType, null)], db) { _metaType = metaType; } /// /// Recursively executes INSERT commands for the specified and all its /// one-to-one and one-to-many associations. /// /// /// The object whose INSERT command is to be executed. This parameter is named entity for consistency /// with the other CRUD methods, but in this case it doesn't need to be an actual entity, which means it doesn't /// need to have a primary key. /// public void Add(TEntity entity) { ArgumentNullException.ThrowIfNull(entity); var idMember = _metaType.DBGeneratedIdentityMember; var outputIdMember = idMember is not null && _db.Configuration.SqlDialect is SqlDialect.TSql; var syncMembers = _metaType.PersistentDataMembers .Where(m => m.AutoSync is AutoSync.Always or AutoSync.OnInsert && m != idMember) .ToArray(); var insertSql = BuildInsertStatementForEntity(entity, outputIdMember); var id = default(object); using (var tx = _db.EnsureInTransaction()) { if (outputIdMember) { // this block emulates Database.Execute() var cmd = _db.CreateCommand(insertSql); try { id = cmd.ExecuteScalar(); } catch { _db.Trace(cmd, error: true); throw; } _db.Trace(cmd); } else { _db.Execute(insertSql, affect: 1, exact: true); if (idMember is not null) { id = _db.LastInsertId(); } } if (idMember is not null) { var convertedId = Convert.ChangeType(id, idMember.Type, CultureInfo.InvariantCulture); var entityObj = (object)entity; idMember.MemberAccessor.SetBoxedValue(ref entityObj, convertedId); } if (syncMembers.Length > 0 && _metaType.IsEntity) { Refresh(entity, syncMembers); } InsertDescendants(entity); tx.Commit(); } } void InsertDescendants(TEntity entity) { InsertOneToOne(entity); InsertOneToMany(entity); } void InsertOneToOne(TEntity entity) { foreach (var assoc in _metaType.Associations .Where(a => !a.IsMany && a.ThisKeyIsPrimaryKey && a.OtherKeyIsPrimaryKey)) { var child = assoc.ThisMember.MemberAccessor.GetBoxedValue(entity); if (child is null) { continue; } for (int j = 0; j < assoc.ThisKey.Count; j++) { var thisKey = assoc.ThisKey[j]; var otherKey = assoc.OtherKey[j]; var thisKeyVal = thisKey.MemberAccessor.GetBoxedValue(entity); otherKey.MemberAccessor.SetBoxedValue(ref child, thisKeyVal); } var otherTable = _db.Table(assoc.OtherType); otherTable.Add(child); } } void InsertOneToMany(TEntity entity) { foreach (var assoc in _metaType.Associations.Where(a => a.IsMany)) { var many = ((IEnumerable)assoc.ThisMember.MemberAccessor.GetBoxedValue(entity) ?? []) .Where(o => o is not null) .ToArray(); if (many.Length == 0) { continue; } foreach (var child in many) { for (int k = 0; k < assoc.ThisKey.Count; k++) { var thisKey = assoc.ThisKey[k]; var otherKey = assoc.OtherKey[k]; var thisKeyVal = thisKey.MemberAccessor.GetBoxedValue(entity); var c = child; otherKey.MemberAccessor.SetBoxedValue(ref c, thisKeyVal); } } var otherTable = _db.Table(assoc.OtherType); otherTable.AddRange(many); } } /// /// Recursively executes INSERT commands for the specified and all their /// one-to-one and one-to-many associations. /// /// The entities whose INSERT commands are to be executed. public void AddRange(IEnumerable entities) { ArgumentNullException.ThrowIfNull(entities); AddRange(entities as TEntity[] ?? entities.ToArray()); } /// public void AddRange(params TEntity[] entities) { ArgumentNullException.ThrowIfNull(entities); entities = entities.Where(o => o is not null) .ToArray(); if (entities.Length == 0) { return; } if (entities.Length == 1) { Add(entities[0]); return; } var syncMembers = _metaType.PersistentDataMembers .Where(m => m.AutoSync is AutoSync.Always or AutoSync.OnInsert) .ToArray(); var batch = syncMembers.Length == 0 && _db.Configuration.EnableBatchCommands; if (batch) { var batchInsert = SqlBuilder.JoinSql( ";" + Environment.NewLine, entities.Select(e => BuildInsertStatementForEntity(e))); using (var tx = _db.EnsureInTransaction()) { _db.Execute(batchInsert, affect: entities.Length, exact: true); foreach (var e in entities) { InsertDescendants(e); } tx.Commit(); } } else { using (var tx = _db.EnsureInTransaction()) { foreach (var e in entities) { Add(e); } tx.Commit(); } } } /// /// Executes an UPDATE command for the specified . /// /// The entity whose UPDATE command is to be executed. public void Update(TEntity entity) => Update(entity, null); /// /// The original primary key value. /// This overload is helpful when the entity uses an assigned primary key. public void Update(TEntity entity, object? originalId) { ArgumentNullException.ThrowIfNull(entity); var updateSql = BuildUpdateStatementForEntity(entity, originalId); var syncMembers = _metaType.PersistentDataMembers .Where(m => m.AutoSync is AutoSync.Always or AutoSync.OnUpdate) .ToArray(); using (_db.EnsureConnectionOpen()) { _db.Execute(updateSql, affect: 1, exact: true); if (syncMembers.Length > 0) { Refresh(entity, syncMembers); } } } /// /// Executes UPDATE commands for the specified . /// /// The entities whose UPDATE commands are to be executed. public void UpdateRange(IEnumerable entities) { ArgumentNullException.ThrowIfNull(entities); UpdateRange(entities as TEntity[] ?? entities.ToArray()); } /// /// Executes UPDATE commands for the specified . /// /// The entities whose UPDATE commands are to be executed. public void UpdateRange(params TEntity[] entities) { ArgumentNullException.ThrowIfNull(entities); entities = entities.Where(o => o is not null) .ToArray(); if (entities.Length == 0) { return; } if (entities.Length == 1) { Update(entities[0]); return; } EnsureEntityType(); var syncMembers = _metaType.PersistentDataMembers .Where(m => m.AutoSync is AutoSync.Always or AutoSync.OnUpdate) .ToArray(); var batch = syncMembers.Length == 0 && _db.Configuration.EnableBatchCommands; if (batch) { var batchUpdate = SqlBuilder.JoinSql( ";" + Environment.NewLine, entities.Select(e => BuildUpdateStatementForEntity(e))); _db.Execute(batchUpdate, affect: entities.Length, exact: true); } else { using (var tx = _db.EnsureInTransaction()) { foreach (var e in entities) { Update(e); } tx.Commit(); } } } /// /// Executes a DELETE command for the specified . /// /// The entity whose DELETE command is to be executed. /// true if is deleted; otherwise, false. public bool Remove(TEntity entity) { ArgumentNullException.ThrowIfNull(entity); var deleteSql = BuildDeleteStatementForEntity(entity); var usingVersion = _db.Configuration.UseVersionMember && _metaType.VersionMember is not null; return _db.Execute(deleteSql, affect: 1, exact: usingVersion) == 1; } /// /// Executes a DELETE command for the entity /// whose primary key matches the parameter. /// /// The primary key value. /// true if a record that matches was found and deleted; otherwise, false. public bool RemoveKey(object id) { ArgumentNullException.ThrowIfNull(id); var deleteSql = BuildDeleteStatementForKey(id); return _db.Execute(deleteSql, affect: 1) == 1; } /// /// Executes DELETE commands for the specified . /// /// The entities whose DELETE commands are to be executed. public void RemoveRange(IEnumerable entities) { ArgumentNullException.ThrowIfNull(entities); RemoveRange(entities as TEntity[] ?? entities.ToArray()); } /// /// Executes DELETE commands for the specified . /// /// The entities whose DELETE commands are to be executed. public void RemoveRange(params TEntity[] entities) { ArgumentNullException.ThrowIfNull(entities); entities = entities.Where(o => o is not null) .ToArray(); if (entities.Length == 0) { return; } if (entities.Length == 1) { Remove(entities[0]); return; } EnsureEntityType(); var usingVersion = _db.Configuration.UseVersionMember && _metaType.VersionMember is not null; var singleStatement = _metaType.IdentityMembers.Count == 1 && !usingVersion; var batch = _db.Configuration.EnableBatchCommands; if (singleStatement) { var idMember = _metaType.IdentityMembers[0]; var ids = entities.Select(e => idMember.GetValueForDatabase(e)) .ToArray(); var sql = BuildDeleteStatement() .WHERE(String.Empty); var sb = sql.Buffer; _db.QuoteIdentifier(sb, idMember.MappedName); sb.Append(" IN ("); for (int i = 0; i < ids.Length; i++) { if (i > 0) { sb.Append(',') .Append(' '); } sb.Append('{') .Append(sql.ParameterValues.Count) .Append('}'); sql.ParameterValues.Add(ids[i]); } sb.Append(')'); _db.Execute(sql, affect: entities.Length); } else if (batch) { var batchDelete = SqlBuilder.JoinSql( ";" + Environment.NewLine, entities.Select(e => BuildDeleteStatementForEntity(e))); _db.Execute(batchDelete, affect: entities.Length, exact: usingVersion); } else { using (var tx = _db.EnsureInTransaction()) { foreach (var e in entities) { Remove(e); } tx.Commit(); } } } /// /// Sets all column members of to their most current persisted value. /// /// The entity to refresh. public void Refresh(TEntity entity) => Refresh(entity, null); void Refresh(TEntity entity, IEnumerable? refreshMembers) { ArgumentNullException.ThrowIfNull(entity); EnsureEntityType(); var query = BuildSelectStatement(refreshMembers); query.WHERE(_db.BuildPredicateFragment(entity, _metaType.IdentityMembers, query.ParameterValues)); var mapper = _db.CreatePocoMapper(_metaType.Type); var entityObj = (object)entity; _ = _db.Map(query, r => { mapper.PocoLoad(entityObj, r); return null; }).SingleOrDefault(); } void EnsureEntityType() => SqlTable.EnsureEntityType(_metaType); // ISqlTable Members void ISqlTable.Add(object entity) => Add((TEntity)entity); void ISqlTable.AddRange(IEnumerable entities) => AddRange(entities.Cast()); void ISqlTable.AddRange(params object[] entities) => AddRange(entities.Cast()); void ISqlTable.Update(object entity) => Update((TEntity)entity); void ISqlTable.Update(object entity, object? originalId) => Update((TEntity)entity, originalId); void ISqlTable.UpdateRange(IEnumerable entities) => UpdateRange(entities.Cast()); void ISqlTable.UpdateRange(params object[] entities) => UpdateRange(entities.Cast()); bool ISqlTable.Remove(object entity) => Remove((TEntity)entity); bool ISqlTable.RemoveKey(object id) => RemoveKey(id); void ISqlTable.RemoveRange(IEnumerable entities) => RemoveRange(entities.Cast()); void ISqlTable.RemoveRange(params object[] entities) => RemoveRange(entities.Cast()); void ISqlTable.Refresh(object entity) => Refresh((TEntity)entity); // Statement building SqlBuilder BuildSelectStatement(IEnumerable? selectMembers) { var sql = new SqlBuilder() .SELECT(String.Empty); _db.SelectBody(sql.Buffer, _metaType, selectMembers, null); sql.FROM(_db.FromBody(_metaType)); return sql; } SqlBuilder BuildInsertStatementForEntity(TEntity entity) => BuildInsertStatementForEntity(entity, false); SqlBuilder BuildInsertStatementForEntity(TEntity entity, bool outputIdMember) { ArgumentNullException.ThrowIfNull(entity); var insertingMembers = _metaType.PersistentDataMembers .Where(m => !m.IsAssociation && !m.IsDbGenerated) .ToArray(); var parameters = insertingMembers .Select(m => m.GetValueForDatabase(entity)) .ToArray(); var sql = new SqlBuilder(); var sb = sql.Buffer .Append("INSERT INTO "); _db.QuoteIdentifier(sb, _metaType.Table.TableName); sb.Append(" ("); for (int i = 0; i < insertingMembers.Length; i++) { if (i > 0) { sb.Append(", "); } _db.QuoteIdentifier(sb, insertingMembers[i].MappedName); } sb.Append(')'); if (outputIdMember && _metaType.DBGeneratedIdentityMember is { } idMember) { sb.AppendLine() .Append("OUTPUT INSERTED."); _db.QuoteIdentifier(sb, idMember.MappedName); } sb.AppendLine() .Append("VALUES ("); for (int i = 0; i < insertingMembers.Length; i++) { if (i > 0) { sb.Append(", "); } sb.Append('{') .Append(i) .Append('}'); } sb.Append(')'); foreach (var item in parameters) { sql.ParameterValues.Add(item); } return sql; } SqlBuilder BuildUpdateStatementForEntity(TEntity entity) => BuildUpdateStatementForEntity(entity, null); SqlBuilder BuildUpdateStatementForEntity(TEntity entity, object? originalId) { ArgumentNullException.ThrowIfNull(entity); EnsureEntityType(); var updatingMembers = _metaType.PersistentDataMembers .Where(m => !m.IsAssociation && !m.IsDbGenerated) .ToArray(); var predicateMembers = _metaType.PersistentDataMembers .Where(m => m.IsPrimaryKey || (m.IsVersion && _db.Configuration.UseVersionMember)) .ToArray(); if (originalId is not null && predicateMembers.Count(m => m.IsPrimaryKey) > 1) { throw new InvalidOperationException("The operation is not supported for entities with more than one identity member."); } var sql = new SqlBuilder(); var parametersBuffer = sql.ParameterValues; var sb = sql.Buffer .Append("UPDATE "); _db.QuoteIdentifier(sb, _metaType.Table.TableName); sb.AppendLine() .Append("SET "); for (int i = 0; i < updatingMembers.Length; i++) { if (i > 0) { sb.Append(", "); } var member = updatingMembers[i]; var value = member.GetValueForDatabase(entity); _db.QuoteIdentifier(sb, member.MappedName); sb.Append(" = {") .Append(parametersBuffer.Count) .Append('}'); parametersBuffer.Add(value); } var getValuefn = default(Func); if (originalId is not null) { getValuefn = m => (m.IsPrimaryKey) ? m.ConvertValueForDatabase(originalId) : m.GetValueForDatabase(entity); } sb.AppendLine() .Append("WHERE ") .Append(_db.BuildPredicateFragment(entity, predicateMembers, parametersBuffer, getValuefn)); return sql; } SqlBuilder BuildDeleteStatement() { var sql = new SqlBuilder() .Append("DELETE FROM "); _db.QuoteIdentifier(sql.Buffer, _metaType.Table.TableName); return sql; } SqlBuilder BuildDeleteStatementForEntity(TEntity entity) { ArgumentNullException.ThrowIfNull(entity); EnsureEntityType(); var predicateMembers = _metaType.PersistentDataMembers .Where(m => m.IsPrimaryKey || (m.IsVersion && _db.Configuration.UseVersionMember)); var deleteSql = BuildDeleteStatement(); deleteSql.WHERE(_db.BuildPredicateFragment(entity, predicateMembers, deleteSql.ParameterValues)); return deleteSql; } SqlBuilder BuildDeleteStatementForKey(object id) { ArgumentNullException.ThrowIfNull(id); EnsureEntityType(); if (_metaType.IdentityMembers.Count > 1) { throw new InvalidOperationException("Cannot call this method when the entity has more than one identity member."); } var deleteSql = BuildDeleteStatement() .WHERE(String.Empty); var sb = deleteSql.Buffer; _db.QuoteIdentifier(sb, _metaType.IdentityMembers[0].MappedName); sb.Append(" = {") .Append(deleteSql.ParameterValues.Count) .Append('}'); deleteSql.ParameterValues.Add(id); return deleteSql; } } partial interface ISqlTable { string Name { get; } void Add(object entity); void AddRange(IEnumerable entities); void AddRange(params object[] entities); bool Remove(object entity); bool RemoveKey(object id); void RemoveRange(IEnumerable entities); void RemoveRange(params object[] entities); void Refresh(object entity); void Update(object entity); void Update(object entity, object? originalId); void UpdateRange(IEnumerable entities); void UpdateRange(params object[] entities); } partial class PocoNode { ColumnAttribute? _columnAttribute; private ColumnAttribute? ColumnAttribute => _columnAttribute ??= this.Property?.GetCustomAttribute(); partial void GetConvertToType(ref Type? convertToType) { convertToType = this.ColumnAttribute?.ConvertTo; } } ================================================ FILE: src/DbExtensions-QE/DbExtensions-QE.csproj ================================================  DbExtensions $(AssemblyName) Query Edition $(AssemblyName)-QE README.md $(DefineConstants);DBEX_QE ================================================ FILE: src/DbExtensions-QE/README.md ================================================ DbExtensions-QE (Query Edition) is a version of DbExtensions that excludes: - SqlTable, SqlTable<T> - Annotations (TableAttribute, ColumnAttribute, etc.) - SqlSet methods that depend on annotations (Contains, ContainsKey, Find, Include) - Internal Metadata namespace Query Edition is intended for projects where the CRUD operations are source-generated, or implemented using another ORM. ================================================ FILE: src/DbExtensions.SqlBuilder/DbExtensions.SqlBuilder.csproj ================================================  net8.0 12 ================================================ FILE: src/DbExtensions.SqlBuilder/README.md ================================================ This project is here to make sure [SqlBuilder][1] compiles as a standalone component. [1]: ../DbExtensions/SqlBuilder.cs ================================================ FILE: src/DbExtensions.SqlSet/DbExtensions.SqlSet.csproj ================================================  net8.0 12 ================================================ FILE: src/DbExtensions.SqlSet/README.md ================================================ This project is here to make sure [SqlSet][1] compiles without any references to mapping components. [1]: ../DbExtensions/SqlSet.cs ================================================ FILE: tests/DbExtensions.Tests/DbExtensions.Tests.csproj ================================================  net8.0 12 false ================================================ FILE: tests/DbExtensions.Tests/Mapping/DynamicMappingBehavior.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; namespace DbExtensions.Tests.Mapping { using static TestUtil; [TestFixture] public class DynamicMappingBehavior { [Test] public void Constructor_Parameters_Not_Allowed() { var data = new Dictionary { { "1", "foo" } }; var db = MockQuery(data); var results = db.Map(SQL .SELECT("NULL")); Assert.Throws(() => results.Single()); } } } ================================================ FILE: tests/DbExtensions.Tests/Mapping/EnumMappingBehavior.cs ================================================ using NUnit.Framework; namespace DbExtensions.Tests.Mapping.Annotated { using static TestUtil; [TestFixture] public class EnumMappingBehavior { readonly Database db = RealDatabase(); [Test] public void Can_Map_Numeric_Column_To_Enum() { var item = db.Table() .First($"CategoryID = {Enum.CategoryEnum.Condiments}"); Assert.AreEqual(Enum.CategoryEnum.Condiments, item.CategoryID); Assert.AreEqual((int)Enum.CategoryEnum.Condiments, (int)item.CategoryID); } [Test] public void Can_Map_Numeric_Column_To_Nullable_Enum() { var item = db.Table() .First($"CategoryID = {Enum.CategoryEnum.Condiments}"); Assert.AreEqual(Enum.CategoryEnum.Condiments, item.CategoryID); Assert.AreEqual((int)Enum.CategoryEnum.Condiments, (int)item.CategoryID); } [Test] public void Can_Persist_Enum_To_Numeric_Column() { using (var tx = db.EnsureInTransaction()) { var table = db.Table(); var item = new Enum.ToNumericColumn.Product { CategoryID = Enum.CategoryEnum.Beverages, ProductName = "" }; table.Add(item); Assert.AreEqual(1, table.Count($"ProductID = {item.ProductID} AND CategoryID = {item.CategoryID}")); tx.Rollback(); } } [Test] public void Can_Persist_Nullable_Enum_To_Numeric_Column() { using (var tx = db.EnsureInTransaction()) { var table = db.Table(); var item = new Enum.NullableToNumericColumn.Product { CategoryID = Enum.CategoryEnum.Beverages, ProductName = "" }; table.Add(item); Assert.AreEqual(1, table.Count($"ProductID = {item.ProductID} AND CategoryID = {item.CategoryID}")); tx.Rollback(); } } [Test] public void Can_Map_Text_Column_To_Enum() { var item = db.Table() .Single($"CategoryName = {Enum.CategoryEnum.Condiments.ToString()}"); Assert.AreEqual(Enum.CategoryEnum.Condiments, item.CategoryName); Assert.AreEqual(Enum.CategoryEnum.Condiments.ToString(), item.CategoryName.ToString()); } [Test] public void Can_Map_Text_Column_To_Nullable_Enum() { var item = db.Table() .Single($"CategoryName = {Enum.CategoryEnum.Condiments.ToString()}"); Assert.AreEqual(Enum.CategoryEnum.Condiments, item.CategoryName); Assert.AreEqual(Enum.CategoryEnum.Condiments.ToString(), item.CategoryName.ToString()); } [Test] public void Can_Persist_Enum_To_Text_Column() { using (var tx = db.EnsureInTransaction()) { var table = db.Table(); var item = new Enum.ToTextColumn.Category { CategoryName = Enum.CategoryEnum.Foo }; table.Add(item); Assert.AreEqual(1, table.Count($"CategoryID = {item.CategoryID} AND CategoryName = {item.CategoryName.ToString()}")); item.CategoryName = Enum.CategoryEnum.Bar; table.Update(item); Assert.AreEqual(1, table.Count($"CategoryID = {item.CategoryID} AND CategoryName = {item.CategoryName.ToString()}")); tx.Rollback(); } } [Test] public void Can_Persist_Nullable_Enum_To_Text_Column() { using (var tx = db.EnsureInTransaction()) { var table = db.Table(); var item = new Enum.NullableToTextColumn.Category { CategoryName = Enum.CategoryEnum.Foo }; table.Add(item); Assert.AreEqual(1, table.Count($"CategoryID = {item.CategoryID} AND CategoryName = {item.CategoryName.ToString()}")); item.CategoryName = Enum.CategoryEnum.Bar; table.Update(item); Assert.AreEqual(1, table.Count($"CategoryID = {item.CategoryID} AND CategoryName = {item.CategoryName.ToString()}")); tx.Rollback(); } } } namespace Enum { public enum CategoryEnum { Beverages = 1, Condiments = 2, Foo = 1000, Bar = 1001 } namespace ToNumericColumn { [Table(Name = "Products")] public class Product { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int ProductID { get; set; } [Column] public string ProductName { get; set; } [Column] public CategoryEnum CategoryID { get; set; } } } namespace NullableToNumericColumn { [Table(Name = "Products")] public class Product { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int ProductID { get; set; } [Column] public string ProductName { get; set; } [Column] public CategoryEnum? CategoryID { get; set; } } } namespace ToTextColumn { [Table(Name = "Categories")] public class Category { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int CategoryID { get; set; } [Column(ConvertTo = typeof(string))] public CategoryEnum CategoryName { get; set; } } } namespace NullableToTextColumn { [Table(Name = "Categories")] public class Category { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int CategoryID { get; set; } [Column(ConvertTo = typeof(string))] public CategoryEnum? CategoryName { get; set; } } } } } ================================================ FILE: tests/DbExtensions.Tests/Mapping/PersistentComplexPropertiesBehavior.cs ================================================ using NUnit.Framework; namespace DbExtensions.Tests.Mapping.Annotated { using static TestUtil; [TestFixture] public class PersistentComplexPropertiesBehavior() { readonly Database db = RealDatabase(); [Test] public void Can_Read_Default_Name() { var entity = db.Table() .Find("ANATR"); Assert.IsNotNull(entity); Assert.IsNotNull(entity.Contact); Assert.AreEqual("Ana Trujillo", entity.Contact.Name); Assert.AreEqual("Owner", entity.Contact.Title); } [Test] public void Can_Read_Custom_Name() { var entity = db.Table() .Find("ANATR"); Assert.IsNotNull(entity); Assert.IsNotNull(entity.CustomerContact); Assert.AreEqual("Ana Trujillo", entity.CustomerContact.Name); Assert.AreEqual("Owner", entity.CustomerContact.Title); } [Test] public void Can_Insert() { using (var tx = db.EnsureInTransaction()) { var table = db.Table(); var entity = new PersistentComplexProperties.Insert.Customer { CustomerID = "XXXXX", CompanyName = "X5 Corp.", Contact = new PersistentComplexProperties.Insert.Contact { Name = "Mr. X", Title = "Owner" } }; table.Add(entity); entity = table.Find(entity.CustomerID); Assert.IsNotNull(entity); Assert.AreEqual("XXXXX", entity.CustomerID); Assert.IsNotNull(entity.Contact); Assert.AreEqual("Mr. X", entity.Contact.Name); tx.Rollback(); } } [Test] public void Can_Update() { using (var tx = db.EnsureInTransaction()) { var table = db.Table(); var entity = table.Find("ANATR"); Assert.AreEqual("Ana Trujillo", entity.Contact.Name); entity.Contact.Name = "Ana Torroja"; table.Update(entity); entity = table.Find(entity.CustomerID); Assert.AreEqual("Ana Torroja", entity.Contact.Name); tx.Rollback(); } } [Test] public void Can_Update_Null_Complex_Property() { using (var tx = db.EnsureInTransaction()) { var table = db.Table(); var entity = table.Find("ANATR"); Assert.AreEqual("Ana Trujillo", entity.Contact.Name); entity.Contact = null; table.Update(entity); Assert.IsTrue(table.Any($"CustomerID = {entity.CustomerID} AND ContactName IS NULL AND ContactTitle IS NULL")); entity = table.Find(entity.CustomerID); Assert.IsNull(entity.Contact); tx.Rollback(); } } [Test] public void Can_Configure_Default_Separator() { var db = MockDatabase(); db.Configuration.DefaultComplexPropertySeparator = "$"; var expected = SQL .SELECT(db.QuoteIdentifier("CustomerID")) ._(db.QuoteIdentifier("CompanyName")) ._(db.QuoteIdentifier("Contact$Name")) ._(db.QuoteIdentifier("Contact$Title")) .FROM(db.QuoteIdentifier("Customers")); var actual = db.Table(); Assert.IsTrue(SqlEquals(actual, expected)); } [Test] public void Can_Override_Default_Separator() { var db = MockDatabase(); db.Configuration.DefaultComplexPropertySeparator = "$"; var expected = SQL .SELECT(db.QuoteIdentifier("CustomerID")) ._(db.QuoteIdentifier("CompanyName")) ._(db.QuoteIdentifier("Contact_Name") + " AS " + db.QuoteIdentifier("Contact$Name")) ._(db.QuoteIdentifier("Contact_Title") + " AS " + db.QuoteIdentifier("Contact$Title")) .FROM(db.QuoteIdentifier("Customers")); var actual = db.Table(); Assert.IsTrue(SqlEquals(actual, expected)); } [Test] public void Can_Override_Default_Separator_With_Empty_String() { var db = MockDatabase(); db.Configuration.DefaultComplexPropertySeparator = "$"; var expected = SQL .SELECT(db.QuoteIdentifier("CustomerID")) ._(db.QuoteIdentifier("CompanyName")) ._(db.QuoteIdentifier("ContactName") + " AS " + db.QuoteIdentifier("Contact$Name")) ._(db.QuoteIdentifier("ContactTitle") + " AS " + db.QuoteIdentifier("Contact$Title")) .FROM(db.QuoteIdentifier("Customers")); var actual = db.Table(); Assert.IsTrue(SqlEquals(actual, expected)); } } namespace PersistentComplexProperties { namespace DefaultName { [Table(Name = "Customers")] class Customer { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column] public string CompanyName { get; set; } [ComplexProperty] public Contact Contact { get; set; } } class Contact { [Column] public string Name { get; set; } [Column] public string Title { get; set; } } } namespace CustomName { [Table(Name = "Customers")] class Customer { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column] public string CompanyName { get; set; } [ComplexProperty(Name = "Contact")] public Contact CustomerContact { get; set; } } class Contact { [Column] public string Name { get; set; } [Column] public string Title { get; set; } } } namespace Insert { [Table(Name = "Customers")] class Customer { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column] public string CompanyName { get; set; } [ComplexProperty] public Contact Contact { get; set; } } class Contact { [Column] public string Name { get; set; } [Column] public string Title { get; set; } } } namespace Update { [Table(Name = "Customers")] class Customer { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column] public string CompanyName { get; set; } [ComplexProperty] public Contact Contact { get; set; } } class Contact { [Column] public string Name { get; set; } [Column] public string Title { get; set; } } } namespace UpdateNullComplexProperty { [Table(Name = "Customers")] class Customer { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column] public string CompanyName { get; set; } [ComplexProperty] public Contact Contact { get; set; } } class Contact { [Column] public string Name { get; set; } [Column] public string Title { get; set; } } } namespace ConfigureSeparator { [Table(Name = "Customers")] class Customer { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column] public string CompanyName { get; set; } [ComplexProperty] public Contact Contact { get; set; } } class Contact { [Column] public string Name { get; set; } [Column] public string Title { get; set; } } } namespace OverrideSeparator { [Table(Name = "Customers")] class Customer { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column] public string CompanyName { get; set; } [ComplexProperty(Separator = "_")] public Contact Contact { get; set; } } class Contact { [Column] public string Name { get; set; } [Column] public string Title { get; set; } } } namespace OverrideSeparatorEmptyString { [Table(Name = "Customers")] class Customer { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column] public string CompanyName { get; set; } [ComplexProperty(Separator = "")] public Contact Contact { get; set; } } class Contact { [Column] public string Name { get; set; } [Column] public string Title { get; set; } } } } } ================================================ FILE: tests/DbExtensions.Tests/Mapping/PocoMappingBehavior.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; namespace DbExtensions.Tests.Mapping.Poco { using static TestUtil; [TestFixture] public class PocoMappingBehavior() { [Test] public void Map_Property() { var data = new Dictionary { { "Foo", "a" } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual("a", value.Foo); } [Test] public void Map_Null_Property() { var data = new Dictionary { { "Foo", null } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.IsNull(value.Foo); } [Test] public void Map_Object() { var data = new Dictionary { { "Foo", "a" } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual("a", value.Foo); } [Test] public void Map_Property_Private_Setter() { var data = new Dictionary { { "Foo", "a" } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual("a", value.Foo); } [Test] public void Ignore_Unmapped_Property() { var data = new Dictionary { { "Foo", "a" }, { "Bar", "b" } }; var db = MockQuery(data); _ = db.Map(SQL .SELECT("NULL")) .Single(); } [Test] public void Map_Complex_Property() { var data = new Dictionary { { "Bar$Foo", "b" } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.IsNotNull(value.Bar); Assert.AreEqual("b", value.Bar.Foo); } [Test] public void Map_Null_Complex_Property() { var data = new Dictionary { { "Bar", null } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.IsNull(value.Bar); } [Test] public void Map_Complex_Property_To_Null_When_All_Subproperties_Are_Null() { var data = new Dictionary { { "Nested$Foo", null }, { "Nested$Bar", null } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.IsNull(value.Nested); } [Test] public void Load_Complex_Property() { var data = new Dictionary { { "Foo$B", 2 } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual(1, value.Foo.A); } [Test] public void Map_Constructor() { var data = new Dictionary { { "1", 5 }, { "2", "b" } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual(5, value.Foo); Assert.AreEqual("b", value.Bar); } [Test] public void Fail_When_Duplicate_Arguments() { var data = new KeyValuePair[] { new("1", "http://example.com"), new("1", "http://example.com"), }; var db = MockQuery(data); var results = db.Map(SQL .SELECT("NULL")); Assert.Throws(() => results.Single()); } [Test] public void Fail_When_Multiple_Constructors_With_Same_Number_Of_Parameters() { var data = new Dictionary { { "1", "http://example.com" }, { "2", 1 } }; var db = MockQuery(data); var results = db.Map(SQL .SELECT("NULL")); Assert.Throws(() => results.Single()); } [Test] public void Map_Constructor_Complex_Property() { var data = new Dictionary { { "Url$1", "http://example.com" } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.IsNotNull(value.Url); Assert.AreEqual("http://example.com", value.Url.OriginalString); } [Test] public void Map_Constructor_Nullable_Complex_Property() { var data = new Dictionary { { "Foo1$1", 1 }, { "Foo2", null } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual(1, value.Foo1.Value.A); Assert.IsNull(value.Foo2); } [Test] public void Map_Constructor_Complex_Property_To_Null_When_All_Arguments_And_Subproperties_Are_Null() { var data = new Dictionary { { "Foo$1", null }, { "Foo$Foo", null } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.IsNull(value.Foo); } [Test] public void Map_Constructor_Complex_Argument_To_Null_When_All_Arguments_And_Subproperties_Are_Null() { var data = new Dictionary { { "1$1", null }, { "1$Foo", null } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.IsNull(value.Foo); } [Test] public void Load_Constructor_Complex_Property() { var data = new Dictionary { { "1", 1 }, { "Foo$A", 2 }, { "Foo$Bar$B", 2 } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual(1, value.Foo.Bar.A); } [Test] public void Load_Constructor_Complex_Argument() { var data = new Dictionary { { "1$A", 2 }, { "1$Bar$B", 2 } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual(1, value.Foo.Bar.A); } [Test] public void Map_Null_Constructor_Argument() { var data = new Dictionary { { "1", 1 }, { "2", null } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.IsNull(value.Url); } [Test] public void Map_Constructor_Nested() { var data = new Dictionary { { "1$1", 5 }, { "1$2", "b" } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.IsNotNull(value.Nested); Assert.AreEqual(5, value.Nested.Foo); Assert.AreEqual("b", value.Nested.Bar); } } namespace PocoMapping { class Map_Property { public string Foo { get; set; } } class Map_Null_Property { public string Foo { get; set; } } class Map_Object { public string Foo { get; set; } } class Map_Property_Private_Setter { public string Foo { get; private set; } } class Ignore_Unmapped_Property { public string Foo { get; set; } } class Map_Complex_Property { public string Foo { get; set; } public Map_Complex_Property Bar { get; set; } } class Map_Null_Complex_Property { public string Foo { get; set; } public Map_Null_Complex_Property Bar { get; set; } } class Map_Complex_Property_To_Null_When_All_Subproperties_Are_Null { public string Foo { get; set; } public string Bar { get; set; } public Map_Complex_Property_To_Null_When_All_Subproperties_Are_Null Nested { get; set; } } class Load_Complex_Property { public FooClass Foo { get; set; } public Load_Complex_Property() { this.Foo = new FooClass { A = 1 }; } public class FooClass { public int A { get; set; } public int B { get; set; } } } class Map_Constructor { public int Foo { get; } public string Bar { get; } public Map_Constructor(int foo, string bar) { this.Foo = foo; this.Bar = bar; } } class Map_Constructor_Complex_Property { public Uri Url { get; set; } } class Map_Constructor_Nullable_Complex_Property { public Foo? Foo1 { get; set; } public Foo? Foo2 { get; set; } public struct Foo { public readonly int A; public Foo(int a) { this.A = a; } } } class Map_Constructor_Complex_Property_To_Null_When_All_Arguments_And_Subproperties_Are_Null { public FooClass Foo { get; set; } public class FooClass { public string Foo { get; set; } public FooClass(int? id) { } } } class Map_Constructor_Complex_Argument_To_Null_When_All_Arguments_And_Subproperties_Are_Null { public readonly FooClass Foo; public Map_Constructor_Complex_Argument_To_Null_When_All_Arguments_And_Subproperties_Are_Null(FooClass foo) { this.Foo = foo; } public class FooClass { public string Foo { get; set; } public FooClass(int? id) { } } } class Load_Constructor_Complex_Property { public readonly int A; public FooClass Foo { get; set; } public Load_Constructor_Complex_Property(int a) { this.A = a; } public class FooClass { public int A { get; set; } public BarClass Bar { get; set; } public FooClass() { this.Bar = new BarClass { A = 1 }; } public class BarClass { public int A { get; set; } public int B { get; set; } } } } class Load_Constructor_Complex_Argument { public readonly FooClass Foo; public int A { get; set; } public Load_Constructor_Complex_Argument(FooClass foo) { this.Foo = foo; } public class FooClass { public int A { get; set; } public BarClass Bar { get; set; } public FooClass() { this.Bar = new BarClass { A = 1 }; } public class BarClass { public int A { get; set; } public int B { get; set; } } } } class Map_Null_Constructor_Argument { public readonly int Id; public readonly Uri Url; public Map_Null_Constructor_Argument(int id) { this.Id = id; } public Map_Null_Constructor_Argument(int id, Uri url) : this(id) { this.Url = url; } } class Map_Constructor_Nested { public NestedClass Nested { get; } public Map_Constructor_Nested(NestedClass nested) { this.Nested = nested; } public class NestedClass { public int Foo { get; } public string Bar { get; } public NestedClass(int foo, string bar) { this.Foo = foo; this.Bar = bar; } } } } } ================================================ FILE: tests/DbExtensions.Tests/Mapping/PocoMappingConstructorBehavior.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; namespace DbExtensions.Tests.Mapping.Poco { using static TestUtil; [TestFixture] public class PocoMappingConstructorBehavior { [Test] public void Map_Constructor_Named_Arguments() { var data = new Dictionary { { "name", "John" }, { "id", 5 } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual("John", value.nameArg); Assert.AreEqual(5, value.idArg); } [Test] public void Map_Constructor_Named_Arguments_Matching_Properties() { var data = new Dictionary { { "name", "John" }, { "id", 5 } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual("John", value.nameArg); Assert.AreEqual(5, value.idArg); Assert.IsNull(value.name); Assert.AreEqual(0, value.id); } [Test] public void Map_Constructor_Named_Arguments_Missing_Arg() { var data = new Dictionary { { "name", "John" }, { "id", 5 } }; var db = MockQuery(data); var results = db.Map(SQL .SELECT("NULL")); Assert.Throws(() => results.Single()); } [Test] public void Map_Constructor_Named_Arguments_Complex_Property() { var data = new Dictionary { { "prop$name", "John" }, { "prop$id", 5 } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual("John", value.prop.nameArg); Assert.AreEqual(5, value.prop.idArg); } [Test] public void Map_Constructor_Named_Arguments_Complex_Argument() { var data = new Dictionary { { "0$name", "John" }, { "0$id", 5 } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual("John", value.valueArg.nameArg); Assert.AreEqual(5, value.valueArg.idArg); } [Test] public void Map_Constructor_Named_Arguments_Nested() { var data = new Dictionary { { "value$name", "John" }, { "value$id", 5 } }; var db = MockQuery(data); var value = db.Map(SQL .SELECT("NULL")) .Single(); Assert.AreEqual("John", value.valueArg.nameArg); Assert.AreEqual(5, value.valueArg.idArg); } } namespace Constructor.NamedArguments { class _Basic { public readonly int idArg; public readonly string nameArg; public _Basic(int id, string name) { this.idArg = id; this.nameArg = name; } } class _ParamsMatchProperties { public readonly int idArg; public readonly string nameArg; public int id { get; set; } public string name { get; set; } public _ParamsMatchProperties(int id, string name) { this.idArg = id; this.nameArg = name; } } class _MissingArg { public _MissingArg(int id, string name, DateTime dob) { } } class _ComplexProperty { public _ComplexPropertyType prop { get; set; } public class _ComplexPropertyType { public readonly int idArg; public readonly string nameArg; public _ComplexPropertyType(int id, string name) { this.idArg = id; this.nameArg = name; } } } class _ComplexArgument { public readonly _ComplexArgumentType valueArg; public _ComplexArgument(_ComplexArgumentType value) { this.valueArg = value; } public class _ComplexArgumentType { public readonly int idArg; public readonly string nameArg; public _ComplexArgumentType(int id, string name) { this.idArg = id; this.nameArg = name; } } } class _Nested { public readonly _NestedType valueArg; public _Nested(_NestedType value) { this.valueArg = value; } public class _NestedType { public readonly int idArg; public readonly string nameArg; public _NestedType(int id, string name) { this.idArg = id; this.nameArg = name; } } } } } ================================================ FILE: tests/DbExtensions.Tests/Mapping/PocoMappingEnumBehavior.cs ================================================ using NUnit.Framework; namespace DbExtensions.Tests.Mapping.Poco { using static TestUtil; [TestFixture] public class PocoMappingEnumBehavior { readonly Database db = RealDatabase(); [Test] public void Can_Map_Numeric_Column_To_Enum() { var item = db.From("Products") .First($"CategoryID = {Enum.CategoryEnum.Condiments}"); Assert.AreEqual(Enum.CategoryEnum.Condiments, item.CategoryID); Assert.AreEqual((int)Enum.CategoryEnum.Condiments, (int)item.CategoryID); } [Test] public void Can_Map_Numeric_Column_To_Nullable_Enum() { var item = db.From("Products") .First($"CategoryID = {Enum.CategoryEnum.Condiments}"); Assert.AreEqual(Enum.CategoryEnum.Condiments, item.CategoryID); Assert.AreEqual((int)Enum.CategoryEnum.Condiments, (int)item.CategoryID); } [Test] public void Can_Map_Text_Column_To_Enum() { var item = db.From("Categories") .Single($"CategoryName = {Enum.CategoryEnum.Condiments.ToString()}"); Assert.AreEqual(Enum.CategoryEnum.Condiments, item.CategoryName); Assert.AreEqual(Enum.CategoryEnum.Condiments.ToString(), item.CategoryName.ToString()); } [Test] public void Can_Map_Text_Column_To_Nullable_Enum() { var item = db.From("Categories") .Single($"CategoryName = {Enum.CategoryEnum.Condiments.ToString()}"); Assert.AreEqual(Enum.CategoryEnum.Condiments, item.CategoryName); Assert.AreEqual(Enum.CategoryEnum.Condiments.ToString(), item.CategoryName.ToString()); } } namespace Enum { public enum CategoryEnum { Beverages = 1, Condiments = 2, Foo = 1000, Bar = 1001 } namespace ToNumericColumn { public class Product { public int ProductID { get; set; } public string ProductName { get; set; } public CategoryEnum CategoryID { get; set; } } } namespace NullableToNumericColumn { public class Product { public int ProductID { get; set; } public string ProductName { get; set; } public CategoryEnum? CategoryID { get; set; } } } namespace ToTextColumn { public class Category { public int CategoryID { get; set; } public CategoryEnum CategoryName { get; set; } } } namespace NullableToTextColumn { public class Category { public int CategoryID { get; set; } public CategoryEnum? CategoryName { get; set; } } } } } ================================================ FILE: tests/DbExtensions.Tests/Metadata/AssociationReflection.cs ================================================ using System.Collections.ObjectModel; using NUnit.Framework; using DbExtensions.Metadata; namespace DbExtensions.Tests.Metadata { using static TestUtil; [TestFixture] public class AssociationReflection { readonly Database db = MockDatabase(); [Test] public void One_To_Many() { MetaType metaType = db.Configuration.GetMetaType(typeof(Model.Employee)); Assert.AreEqual(2, metaType.Associations.Count); MetaAssociation assoc = metaType.Associations[1]; Assert.IsTrue(assoc.IsMany); Assert.IsFalse(assoc.OtherKeyIsPrimaryKey); Assert.AreEqual(typeof(Model.Employee), assoc.ThisMember.DeclaringType.Type); Assert.AreEqual(nameof(Model.Employee.EmployeeTerritories), assoc.ThisMember.Name); Assert.AreEqual(typeof(Collection), assoc.ThisMember.Type); Assert.AreEqual(typeof(Model.EmployeeTerritory), assoc.OtherMember.DeclaringType.Type); Assert.AreEqual(nameof(Model.EmployeeTerritory.Employee), assoc.OtherMember.Name); Assert.AreEqual(typeof(Model.Employee), assoc.OtherMember.Type); } [Test] public void Many_To_One() { MetaType metaType = db.Configuration.GetMetaType(typeof(Model.EmployeeTerritory)); Assert.AreEqual(2, metaType.Associations.Count); MetaAssociation assoc = metaType.Associations[1]; Assert.IsFalse(assoc.IsMany); Assert.IsTrue(assoc.OtherKeyIsPrimaryKey); Assert.AreEqual(typeof(Model.EmployeeTerritory), assoc.ThisMember.DeclaringType.Type); Assert.AreEqual(nameof(Model.EmployeeTerritory.Employee), assoc.ThisMember.Name); Assert.AreEqual(typeof(Model.Employee), assoc.ThisMember.Type); Assert.AreEqual(typeof(Model.Employee), assoc.OtherMember.DeclaringType.Type); Assert.AreEqual(nameof(Model.Employee.EmployeeTerritories), assoc.OtherMember.Name); Assert.AreEqual(typeof(Collection), assoc.OtherMember.Type); } } namespace Model { [Table] class Employee { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int EmployeeID { get; set; } [Column] public string LastName { get; set; } [Column] public string FirstName { get; set; } [Association(OtherKey = nameof(Order.EmployeeID))] public Collection Orders { get; private set; } [Association(OtherKey = nameof(EmployeeTerritory.EmployeeID))] public Collection EmployeeTerritories { get; private set; } } [Table] class EmployeeTerritory { [Column(IsPrimaryKey = true)] public int EmployeeID { get; set; } [Column(IsPrimaryKey = true)] public string TerritoryID { get; set; } [Association(ThisKey = nameof(TerritoryID))] public Territory Territory { get; set; } [Association(ThisKey = nameof(EmployeeID))] public Employee Employee { get; set; } } [Table] class Territory { [Column(IsPrimaryKey = true)] public string TerritoryID { get; set; } [Column] public string TerritoryDescription { get; set; } } [Table] class Order { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int OrderID { get; set; } [Column] public int? EmployeeID { get; set; } [Association(OtherKey = nameof(OrderDetail.OrderID))] public Collection OrderDetails { get; private set; } [Association(ThisKey = nameof(EmployeeID))] public Employee Employee { get; set; } } [Table] class OrderDetail { [Column(IsPrimaryKey = true)] public int OrderID { get; set; } [Column(IsPrimaryKey = true)] public int ProductID { get; set; } } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlBuilderBehavior/BasicTests.cs ================================================ using System; using NUnit.Framework; namespace DbExtensions.Tests.Querying.SqlBuilderBehavior { [TestFixture] public class BasicTests { [Test] public void Create_Interpolated() { var query = (SqlBuilder)$""" SELECT ProductID, ProductName FROM Products WHERE CategoryID = {1} """; Assert.AreEqual(""" SELECT ProductID, ProductName FROM Products WHERE CategoryID = {0} """, query.ToString()); Assert.AreEqual(1, query.ParameterValues.Count); Assert.AreEqual(1, query.ParameterValues[0]); } [Test] public void Multiple_Parameters() { var query = SQL .SELECT($"{1}, {2}"); Assert.AreEqual("SELECT {0}, {1}", query.ToString()); Assert.AreEqual(2, query.ParameterValues.Count); } [Test] public void Expand_List_Parameter() { var query = SQL .SELECT("*") .WHERE($"c IN ({new[] { 1, 2, 3 }:list})"); Assert.AreEqual("SELECT *\r\nWHERE c IN ({0}, {1}, {2})", query.ToString()); Assert.AreEqual(3, query.ParameterValues.Count); } [Test] public void Adjust_Other_Placeholders_When_Using_List_Parameter() { var query = SQL .SELECT("*") .WHERE($"c IN ({new[] { 1, 2, 3 }:list}) AND c <> {4}"); Assert.AreEqual("SELECT *\r\nWHERE c IN ({0}, {1}, {2}) AND c <> {3}", query.ToString()); Assert.AreEqual(4, query.ParameterValues.Count); } [Test] public void Allow_Empty_List() { var query = SQL .SELECT($"1 IN ({new int[0]:list})"); Assert.AreEqual("SELECT 1 IN ({0})", query.ToString()); Assert.AreEqual(1, query.ParameterValues.Count); Assert.AreEqual(null, query.ParameterValues[0]); } [Test] public void Use_Parameter_On_Limit_Clause() { var query = SQL .SELECT("*") .LIMIT(1); Assert.AreEqual(1, query.ParameterValues.Count); } [Test] public void Use_Parameter_On_Offset_Clause() { var query = SQL .SELECT("*") .OFFSET(1); Assert.AreEqual(1, query.ParameterValues.Count); } [Test] public void Treat_SqlBuilder_As_SubQuery() { var query = SQL .SELECT("*") .FROM($"({SQL .SELECT($"{5}")}) AS t0"); Assert.AreEqual(1, query.ParameterValues.Count); Assert.AreEqual(5, query.ParameterValues[0]); Assert.AreEqual("SELECT *\r\nFROM (\r\n\tSELECT {0}) AS t0", query.ToString()); } [Test] public void Treat_SqlSet_As_SubQuery() { var db = TestUtil.MockDatabase(); var query = SQL .SELECT("*") .FROM($"({db.FromQuery($"SELECT {5}")}) AS t0"); Assert.AreEqual(1, query.ParameterValues.Count); Assert.AreEqual(5, query.ParameterValues[0]); } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlBuilderBehavior/ConditionalAppendTests.cs ================================================ using System; using NUnit.Framework; namespace DbExtensions.Tests.Querying.SqlBuilderBehavior { [TestFixture] public class ConditionalAppendTests { // ## AppendIf [Test] public void AppendIf() { var queryTrue = SQL .SELECT("A") .AppendIf(true, $"B"); Assert.AreEqual("SELECT AB", queryTrue.ToString()); var queryFalse = SQL .SELECT("A") .AppendIf(false, $"B"); Assert.AreEqual("SELECT A", queryFalse.ToString()); } [Test] public void AppendIf_Different_Clause() { var query = SQL .SELECT("A") .WHERE() .AppendIf(true, $"B"); Assert.AreEqual("SELECT AB", query.ToString()); } // ## AppendElseIf [Test] public void AppendElseIf() { var queryTrue = SQL .SELECT("A") .AppendIf(true, $"B") .AppendElseIf(true, $"C"); Assert.AreEqual("SELECT AB", queryTrue.ToString()); var queryFalse = SQL .SELECT("A") .AppendIf(false, $"B") .AppendElseIf(false, $"C") .AppendElseIf(true, $"D"); Assert.AreEqual("SELECT AD", queryFalse.ToString()); } [Test] public void AppendElseIf_No_If() { var query = SQL .SELECT("A") .AppendElseIf(true, $"C"); Assert.AreEqual("SELECT A", query.ToString()); } [Test] public void AppendElseIf_After_Else() { var query = SQL .SELECT("A") .AppendIf(false, $"B") .AppendElse($"C") .AppendElseIf(true, $"D"); Assert.AreEqual("SELECT AC", query.ToString()); } [Test] public void AppendElseIf_Different_Clause() { var query = SQL .SELECT("A") .AppendIf(false, $"B") .WHERE("1 = 1") .AppendElseIf(true, $"C"); Assert.AreEqual("SELECT A\r\nWHERE 1 = 1", query.ToString()); } [Test] public void AppendElseIf_Different_Next_Clause() { var query = SQL .SELECT("A") .AppendIf(false, $"B") .WHERE() .AppendElseIf(true, $"C"); Assert.AreEqual("SELECT A", query.ToString()); } // ## AppendElse [Test] public void AppendElse() { var queryTrue = SQL .SELECT("A") .AppendIf(true, $"B") .AppendElse($"C"); Assert.AreEqual("SELECT AB", queryTrue.ToString()); var queryFalseIf = SQL .SELECT("A") .AppendIf(false, $"B") .AppendElse($"C"); Assert.AreEqual("SELECT AC", queryFalseIf.ToString()); var queryFalseElseIf = SQL .SELECT("A") .AppendIf(false, $"B") .AppendElseIf(false, $"C") .AppendElse($"D"); Assert.AreEqual("SELECT AD", queryFalseElseIf.ToString()); } [Test] public void AppendElse_Duplicate() { var query = SQL .SELECT("A") .AppendIf(false, $"B") .AppendElse($"C") .AppendElse($"D"); Assert.AreEqual("SELECT AC", query.ToString()); } [Test] public void AppendElse_No_If() { var query = SQL .SELECT("A") .AppendElse($"C"); Assert.AreEqual("SELECT A", query.ToString()); } [Test] public void AppendElse_Not_Nested() { var query = SQL .SELECT("A") .AppendIf(false, $"B") .AppendIf(true, $"C") .AppendElse($"D") .AppendElse($"E"); Assert.AreEqual("SELECT AC", query.ToString()); } [Test] public void AppendElse_Different_Clause() { var query = SQL .SELECT("A") .AppendIf(false, $"B") .WHERE("1 = 1") .AppendElse($"C"); Assert.AreEqual("SELECT A\r\nWHERE 1 = 1", query.ToString()); } [Test] public void AppendElse_Different_Next_Clause() { var query = SQL .SELECT("A") .AppendIf(false, $"B") .WHERE() .AppendElse($"C"); Assert.AreEqual("SELECT A", query.ToString()); } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlBuilderBehavior/ConditionalClauseTests.cs ================================================ using System; using NUnit.Framework; namespace DbExtensions.Tests.Querying.SqlBuilderBehavior { [TestFixture] public class ConditionalClauseTests { [Test] public void If_Continuation() { var queryTrue = SQL .SELECT("A") ._If(true, $"B"); Assert.AreEqual("SELECT A, B", queryTrue.ToString()); var queryFalse = SQL .SELECT("A") ._If(false, $"B"); Assert.AreEqual("SELECT A", queryFalse.ToString()); } [Test] public void Next_Clause_Continuation() { var query = SQL .SELECT("A") .WHERE() ._If(true, $"B"); Assert.AreEqual("SELECT A\r\nWHERE B", query.ToString()); } // ## ElseIf_Continuation [Test] public void ElseIf_Continuation() { var queryTrue = SQL .SELECT("A") ._If(true, $"B") ._ElseIf(true, $"C"); Assert.AreEqual("SELECT A, B", queryTrue.ToString()); var queryFalse = SQL .SELECT("A") ._If(false, $"B") ._ElseIf(false, $"C") ._ElseIf(true, $"D"); Assert.AreEqual("SELECT A, D", queryFalse.ToString()); } [Test] public void ElseIf_Continuation_No_If() { var query = SQL .SELECT("A") ._ElseIf(true, $"C"); Assert.AreEqual("SELECT A", query.ToString()); } [Test] public void ElseIf_Continuation_After_Else() { var query = SQL .SELECT("A") ._If(false, $"B") ._Else($"C") ._ElseIf(true, $"D"); Assert.AreEqual("SELECT A, C", query.ToString()); } [Test] public void ElseIf_Continuation_Different_Clause() { var query = SQL .SELECT("A") ._If(false, $"B") .WHERE("1 = 1") ._ElseIf(true, $"C"); Assert.AreEqual("SELECT A\r\nWHERE 1 = 1", query.ToString()); } [Test] public void ElseIf_Continuation_Different_Next_Clause() { var query = SQL .SELECT("A") ._If(false, $"B") .WHERE() ._ElseIf(true, $"C"); Assert.AreEqual("SELECT A", query.ToString()); } // ## Else_Continuation [Test] public void Else_Continuation() { var queryTrue = SQL .SELECT("A") ._If(true, $"B") ._Else($"C"); Assert.AreEqual("SELECT A, B", queryTrue.ToString()); var queryFalseIf = SQL .SELECT("A") ._If(false, $"B") ._Else($"C"); Assert.AreEqual("SELECT A, C", queryFalseIf.ToString()); var queryFalseElseIf = SQL .SELECT("A") ._If(false, $"B") ._ElseIf(false, $"C") ._Else($"D"); Assert.AreEqual("SELECT A, D", queryFalseElseIf.ToString()); } [Test] public void Else_Continuation_Duplicate() { var query = SQL .SELECT("A") ._If(false, $"B") ._Else($"C") ._Else($"D"); Assert.AreEqual("SELECT A, C", query.ToString()); } [Test] public void Else_Continuation_No_If() { var query = SQL .SELECT("A") ._Else($"C"); Assert.AreEqual("SELECT A", query.ToString()); } [Test] public void Else_Continuation_Not_Nested() { var query = SQL .SELECT("A") ._If(false, $"B") ._If(true, $"C") ._Else($"D") ._Else($"E"); Assert.AreEqual("SELECT A, C", query.ToString()); } [Test] public void Else_Continuation_Different_Clause() { var query = SQL .SELECT("A") ._If(false, $"B") .WHERE("1 = 1") ._Else($"C"); Assert.AreEqual("SELECT A\r\nWHERE 1 = 1", query.ToString()); } [Test] public void Else_Continuation_Different_Next_Clause() { var query = SQL .SELECT("A") ._If(false, $"B") .WHERE() ._Else($"C"); Assert.AreEqual("SELECT A", query.ToString()); } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlBuilderBehavior/ExtensibilityTests.cs ================================================ using System.Runtime.CompilerServices; using System.Text; using NUnit.Framework; namespace DbExtensions.Tests.Querying.SqlBuilderBehavior { [TestFixture] public class ExtensibilityTests { [Test] public void Extension_Clause() { var query = ((SqlBuilder)$""" SELECT ProductID, ProductName FROM Products OFFSET {10} ROWS """) .FETCH($"NEXT {5} ROWS ONLY"); Assert.AreEqual(new StringBuilder(""" SELECT ProductID, ProductName FROM Products OFFSET {0} ROWS """) .AppendLine() .Append("FETCH NEXT {1} ROWS ONLY") .ToString() , query.ToString()); Assert.IsTrue(query.CurrentClause is SqlBuilderExtensions.FetchClause); } } public static class SqlBuilderExtensions { public sealed record class FetchClause() : SqlClause("FETCH", null); public static SqlBuilder FETCH(this SqlBuilder sql, [InterpolatedStringHandlerArgument(nameof(sql))] ref SqlBuilder.ClauseStringHandler handler) { return sql; } public static SqlBuilder FETCH(this SqlBuilder sql, string text) { return sql.AppendClause() .Append(text); } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlBuilderBehavior/ValuesClauseTests.cs ================================================ using NUnit.Framework; namespace DbExtensions.Tests.Querying.SqlBuilderBehavior { [TestFixture] public class ValuesClauseTests { [Test] public void Values_List() { var query = SQL .INSERT_INTO("tbl") .VALUES(1, 2, 3); Assert.AreEqual("INSERT INTO tbl\r\nVALUES ({0}, {1}, {2})", query.ToString()); Assert.AreEqual(3, query.ParameterValues.Count); } [Test] public void Values_Continuation() { var query = SQL .INSERT_INTO("tbl") .VALUES(1, 2, 3) .VALUES(4, 5, 6); Assert.AreEqual("INSERT INTO tbl\r\nVALUES ({0}, {1}, {2}),\r\n({3}, {4}, {5})", query.ToString()); Assert.AreEqual(6, query.ParameterValues.Count); } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlSetAnnotatedBehavior/BasicTests.cs ================================================ using NUnit.Framework; namespace DbExtensions.Tests.Querying.SqlSetAnnotatedBehavior { using static TestUtil; [TestFixture] public class BasicTests { readonly Database db = RealDatabase(); [Test] public void Contains() { SqlSet table = db.Table(); var prod1 = table.Single("ProductID = 1"); Assert.IsTrue(table.Contains(prod1)); Assert.IsFalse(table.Where("ProductID = 2").Contains(prod1)); } [Test] public void ContainsKey() { SqlSet table = db.Table(); Assert.IsTrue(table.ContainsKey(1)); Assert.IsFalse(table.Where("ProductID = 2").ContainsKey(1)); } [Test] public void Find() { SqlSet table = db.Table(); Assert.IsNotNull(table.Find(1)); Assert.IsNull(table.Where("ProductID = 2").Find(1)); } } namespace Basic { namespace Model1 { [Table(Name = "Products")] public class Product { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int ProductID { get; set; } public string ProductName { get; set; } } } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlSetAnnotatedBehavior/IncludeTests.cs ================================================ using System; using System.Collections.ObjectModel; using System.Linq; using NUnit.Framework; namespace DbExtensions.Tests.Querying.SqlSetAnnotatedBehavior { using static TestUtil; [TestFixture] public class IncludeTests { readonly Database db = RealDatabase(); [Test] public void Can_Include_One() { var set = db.Table() .Where("NOT CategoryID IS NULL AND NOT SupplierID IS NULL") .Include(p => p.Category) .Include(p => p.Supplier); var item = set.First(); Assert.IsNotNull(item.Category); Assert.IsNotNull(item.Supplier); } [Test] public void Can_Include_One_Nested() { var set = db.Table() .Include(p => p.Territory.Region); var item = set.First(); Assert.IsNotNull(item.Territory); Assert.IsNotNull(item.Territory.Region); } [Test] public void Can_Include_One_Nested_Key_Name_Member_Differs() { var set = db.Table() .Include(p => p.Territory.Region); var item = set.First(); Assert.IsNotNull(item.Territory); Assert.IsNotNull(item.Territory.Region); } [Test] public void Can_Include_Many() { var set = db.Table() .IncludeMany(p => p.Products); var item = set.First(); Assert.IsNotNull(item.Products); Assert.AreNotEqual(0, item.Products.Count); Assert.IsTrue(item.Products.All(p => Object.ReferenceEquals(p.Category, item))); } [Test] public void Can_Include_Many_Multiple() { var set1 = db.Table() .IncludeMany(p => p.EmployeeTerritories); var set2 = set1.IncludeMany(p => p.Orders); var item = set1.First(); Assert.IsNotNull(item.EmployeeTerritories); Assert.AreNotEqual(0, item.EmployeeTerritories.Count); Assert.IsTrue(item.EmployeeTerritories.All(p => Object.ReferenceEquals(p.Employee, item))); // test immutability Assert.IsTrue(item.Orders is null or { Count: 0 }); item = set2.First(); Assert.IsNotNull(item.EmployeeTerritories); Assert.AreNotEqual(0, item.EmployeeTerritories.Count); Assert.IsTrue(item.EmployeeTerritories.All(p => Object.ReferenceEquals(p.Employee, item))); Assert.IsNotNull(item.Orders); Assert.AreNotEqual(0, item.Orders.Count); Assert.IsTrue(item.Orders.All(p => Object.ReferenceEquals(p.Employee, item))); } [Test] public void Can_Include_Many_In_One() { var set = db.Table() .Include(p => p.Employee) .IncludeMany(p => p.Employee.Orders); var item = set.First(); Assert.IsNotNull(item.Employee); Assert.AreNotEqual(0, item.Employee.Orders.Count); Assert.IsTrue(item.Employee.Orders.All(p => Object.ReferenceEquals(p.Employee, item.Employee))); } [Test] public void Can_Include_Many_In_One_Multiple() { var set = db.Table() .Include(p => p.Employee) .IncludeMany(p => p.Employee.Orders) .IncludeMany(p => p.Employee.EmployeeTerritories); var item = set.First(); Assert.IsNotNull(item.Employee); Assert.AreNotEqual(0, item.Employee.Orders.Count); Assert.IsTrue(item.Employee.Orders.All(p => Object.ReferenceEquals(p.Employee, item.Employee))); Assert.AreNotEqual(0, item.Employee.EmployeeTerritories.Count); Assert.IsTrue(item.Employee.EmployeeTerritories.All(p => Object.ReferenceEquals(p.Employee, item.Employee))); } [Test] public void Can_Include_One_In_Many() { var set = db.Table() .IncludeMany(p => p.EmployeeTerritories, set => set .Include(p => p.Territory)); var item = set.First(); Assert.IsNotNull(item.EmployeeTerritories); Assert.AreNotEqual(0, item.EmployeeTerritories.Count); Assert.IsTrue(item.EmployeeTerritories.All(p => p.Territory != null)); } [Test] public void Can_Include_Many_In_Many() { var set = db.Table() .IncludeMany(p => p.Orders, set => set .IncludeMany(p => p.OrderDetails, set => set .Include(p => p.Product)) .OrderBy("OrderID DESC") .Take(5)); var item = set.First(); Assert.IsNotNull(item.Orders); Assert.IsTrue(item.Orders.Count <= 5); foreach (var order in item.Orders) { Assert.IsNotNull(order.OrderDetails); foreach (var det in order.OrderDetails) { Assert.IsNotNull(det.Product); } } } } namespace Include.Model1 { [Table(Name = "Products")] class Product { [Column(IsPrimaryKey = true)] public int ProductID { get; set; } [Column] public int? CategoryID { get; set; } [Column] public int? SupplierID { get; set; } [Association(ThisKey = nameof(CategoryID))] public Category Category { get; set; } [Association(ThisKey = nameof(SupplierID))] public Supplier Supplier { get; set; } } [Table(Name = "Categories")] class Category { [Column(IsPrimaryKey = true)] public int CategoryID { get; set; } [Column] public string CategoryName { get; set; } [Association(OtherKey = nameof(Product.CategoryID))] public Collection Products { get; private set; } } [Table(Name = "Suppliers")] class Supplier { [Column(IsPrimaryKey = true)] public int SupplierID { get; set; } [Column] public string CompanyName { get; set; } } [Table(Name = "Employees")] class Employee { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int EmployeeID { get; set; } [Column] public string LastName { get; set; } [Column] public string FirstName { get; set; } [Association(OtherKey = nameof(EmployeeTerritory.EmployeeID))] public Collection EmployeeTerritories { get; private set; } [Association(OtherKey = nameof(EmployeeTerritory.EmployeeID))] public Collection Orders { get; private set; } } [Table(Name = "EmployeeTerritories")] class EmployeeTerritory { [Column(IsPrimaryKey = true)] public int EmployeeID { get; set; } [Column(IsPrimaryKey = true)] public string TerritoryID { get; set; } [Association(ThisKey = nameof(EmployeeID))] public Employee Employee { get; set; } [Association(ThisKey = nameof(TerritoryID))] public Territory Territory { get; set; } } [Table(Name = "Territories")] class Territory { [Column(IsPrimaryKey = true)] public string TerritoryID { get; set; } [Column] public string TerritoryDescription { get; set; } [Column] public int RegionID { get; set; } [Association(ThisKey = nameof(RegionID))] public Region Region { get; set; } } [Table] class Region { [Column(IsPrimaryKey = true)] public int RegionID { get; set; } [Column] public string RegionDescription { get; set; } } [Table(Name = "Orders")] class Order { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int OrderID { get; set; } [Column] public int? EmployeeID { get; set; } [Association(OtherKey = nameof(OrderDetail.OrderID))] public Collection OrderDetails { get; private set; } [Association(ThisKey = nameof(EmployeeID))] public Employee Employee { get; set; } } [Table(Name = "Order Details")] class OrderDetail { [Column(IsPrimaryKey = true)] public int OrderID { get; set; } [Column(IsPrimaryKey = true)] public int ProductID { get; set; } [Association(ThisKey = nameof(OrderID))] public Order Order { get; set; } [Association(ThisKey = nameof(ProductID))] public Product Product { get; set; } } } namespace Include.Model2 { [Table(Name = "EmployeeTerritories")] class EmployeeTerritory { [Column(IsPrimaryKey = true)] public int EmployeeID { get; set; } [Column(Name = "TerritoryID", IsPrimaryKey = true)] public string Territory_ID { get; set; } [Association(ThisKey = nameof(Territory_ID))] public Territory Territory { get; set; } } [Table(Name = "Territories")] class Territory { [Column(IsPrimaryKey = true)] public string TerritoryID { get; set; } [Column] public string TerritoryDescription { get; set; } [Column(Name = "RegionID")] public int Region_ID { get; set; } [Association(ThisKey = nameof(Region_ID))] public Region Region { get; set; } } [Table] class Region { [Column(IsPrimaryKey = true)] public int RegionID { get; set; } [Column] public string RegionDescription { get; set; } } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlSetAsyncBehavior.cs ================================================ using System.Collections.Generic; using System.Threading.Tasks; using NUnit.Framework; namespace DbExtensions.Tests.Querying { using static TestUtil; [TestFixture] public class SqlSetAsyncBehavior { [Test] public void AsAsyncEnumerable_Reference_Type() { var data = new Dictionary { { "a", "a" } }; var db = MockQuery(data); SqlSet set = db.FromQuery($"SELECT NULL", r => r.GetString(0)); set.AsAsyncEnumerable(); SqlSet untypedSet = set; untypedSet.AsAsyncEnumerable(); } [Test] public void AsAsyncEnumerable_Value_Type() { var data = new Dictionary { { "0", 0 } }; var db = MockQuery(data); SqlSet set = db.FromQuery($"SELECT NULL", r => r.GetInt32(0)); set.AsAsyncEnumerable(); SqlSet untypedSet = set; untypedSet.AsAsyncEnumerable(); } [Test] public async Task Async_Enumerate() { var data = new Dictionary { { "a", "a" } }; var db = MockQuery(data); SqlSet set = db.FromQuery($"SELECT NULL", r => r.GetString(0)); var results = new List(); await foreach (var item in set.AsAsyncEnumerable()) { results.Add(item); } Assert.AreEqual(1, results.Count); Assert.AreEqual(data["a"], results[0]); } [Test] public async Task Async_ForEach_Enumerate() { var data = new Dictionary { { "a", "a" } }; var db = MockQuery(data); SqlSet set = db.FromQuery($"SELECT NULL", r => r.GetString(0)); var results = new List(); await foreach (var item in set) { results.Add(item); } Assert.AreEqual(1, results.Count); Assert.AreEqual(data["a"], results[0]); } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlSetBehavior.cs ================================================ using System.Collections.Generic; using NUnit.Framework; namespace DbExtensions.Tests.Querying { using static TestUtil; [TestFixture] public class SqlSetBehavior { readonly Database db = MockDatabase(); [Test] public void AsEnumerable_Reference_Type() { var data = new Dictionary { { "a", "a" } }; var db = MockQuery(data); SqlSet set = db.FromQuery($"SELECT NULL", r => r.GetString(0)); set.AsEnumerable(); SqlSet untypedSet = set; untypedSet.AsEnumerable(); } [Test] public void AsEnumerable_Value_Type() { var data = new Dictionary { { "0", 0 } }; var db = MockQuery(data); SqlSet set = db.FromQuery($"SELECT NULL", r => r.GetInt32(0)); set.AsEnumerable(); SqlSet untypedSet = set; untypedSet.AsEnumerable(); } [Test] public void Enumerate() { var data = new Dictionary { { "a", "a" } }; var db = MockQuery(data); SqlSet set = db.FromQuery($"SELECT NULL", r => r.GetString(0)); var results = new List(); foreach (var item in set.AsEnumerable()) { results.Add(item); } Assert.AreEqual(1, results.Count); Assert.AreEqual(data["a"], results[0]); } [Test] public void ForEach_Enumerate() { var data = new Dictionary { { "a", "a" } }; var db = MockQuery(data); SqlSet set = db.FromQuery($"SELECT NULL", r => r.GetString(0)); var results = new List(); foreach (var item in set) { results.Add(item); } Assert.AreEqual(1, results.Count); Assert.AreEqual(data["a"], results[0]); } [Test] public void Dont_Use_Subqueries_When_Methods_Are_Called_In_Order() { SqlSet set = db.From("products") .Where("UnitsInStock > 0") .Skip(0) .Take(5); SqlBuilder expected = SQL .SELECT("*") .FROM("products") .WHERE("UnitsInStock > 0") .LIMIT(5) .OFFSET(0); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Apply_Where_After_Where_Call() { SqlSet set = db.From("products") .Where("UnitsInStock > 0") .Where("NOT UnitPrice IS NULL"); SqlBuilder expected = SQL .SELECT("*") .FROM(SQL .SELECT("*") .FROM("products") .WHERE("UnitsInStock > 0"), "_") .WHERE("NOT UnitPrice IS NULL"); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Apply_Where_After_OrderBy_Call() { SqlSet set = db.From("products") .OrderBy("ProductID DESC") .Where("NOT UnitPrice IS NULL"); SqlBuilder expected = SQL .SELECT("*") .FROM(SQL .SELECT("*") .FROM("products") .ORDER_BY("ProductID DESC"), "_") .WHERE("NOT UnitPrice IS NULL"); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Apply_Where_After_Skip_Call() { SqlSet set = db.From("products") .Skip(5) .Where("NOT UnitPrice IS NULL"); SqlBuilder expected = SQL .SELECT("*") .FROM(SQL .SELECT("*") .FROM("products") .OFFSET(5), "_") .WHERE("NOT UnitPrice IS NULL"); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Apply_Where_After_Take_Call() { SqlSet set = db.From("products") .Take(5) .Where("NOT UnitPrice IS NULL"); SqlBuilder expected = SQL .SELECT("*") .FROM(SQL .SELECT("*") .FROM("products") .LIMIT(5), "_") .WHERE("NOT UnitPrice IS NULL"); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Apply_OrderBy_After_OrderBy_Call() { SqlSet set = db.From("products") .OrderBy("ProductID DESC") .OrderBy("UnitPrice"); SqlBuilder expected = SQL .SELECT("*") .FROM(SQL .SELECT("*") .FROM("products") .ORDER_BY("ProductID DESC"), "_") .ORDER_BY("UnitPrice"); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Apply_OrderBy_After_Skip_Call() { SqlSet set = db.From("products") .Skip(5) .OrderBy("UnitPrice"); SqlBuilder expected = SQL .SELECT("*") .FROM(SQL .SELECT("*") .FROM("products") .OFFSET(5), "_") .ORDER_BY("UnitPrice"); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Apply_OrderBy_After_Take_Call() { SqlSet set = db.From("products") .Take(5) .OrderBy("UnitPrice"); SqlBuilder expected = SQL .SELECT("*") .FROM(SQL .SELECT("*") .FROM("products") .LIMIT(5), "_") .ORDER_BY("UnitPrice"); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Apply_Skip_After_Skip_Call() { SqlSet set = db.From("products") .Skip(5) .Skip(1); SqlBuilder expected = SQL .SELECT("*") .FROM(SQL .SELECT("*") .FROM("products") .OFFSET(5), "_") .OFFSET(1); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Apply_Skip_After_Take_Call() { SqlSet set = db.From("products") .Take(5) .Skip(1); SqlBuilder expected = SQL .SELECT("*") .FROM(SQL .SELECT("*") .FROM("products") .LIMIT(5), "_") .OFFSET(1); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Apply_Take_After_Take_Call() { SqlSet set = db.From("products") .Take(5) .Take(1); SqlBuilder expected = SQL .SELECT("*") .FROM(SQL .SELECT("*") .FROM("products") .LIMIT(5), "_") .LIMIT(1); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Dont_Use_Subquery_For_Cast() { SqlSet set = db.From("products") .Cast(typeof(object)) .Where("NOT UnitPrice IS NULL"); SqlBuilder expected = SQL .SELECT("*") .FROM("products") .WHERE("NOT UnitPrice IS NULL"); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Dont_Use_Subquery_For_Cast_Generic() { SqlSet set = db.From("products") .Cast() .Where("NOT UnitPrice IS NULL"); SqlBuilder expected = SQL .SELECT("*") .FROM("products") .WHERE("NOT UnitPrice IS NULL"); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Dont_Require_Type_For_Select() { var data = new Dictionary { { "foo", "a" } }; var db = MockQuery(data); dynamic value = db.FromQuery($"SELECT NULL") .Select("foo") .Single(); Assert.AreEqual("a", value.foo); } [Test] public void Remember_Mapper() { var data = new Dictionary { { "c", "a" } }; var db = MockQuery(data); SqlSet set = db.FromQuery($"SELECT NULL", r => r.GetString(0)) .OrderBy("c"); string value = set.Single(); } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlSetBehaviorForSqlServer.cs ================================================ using NUnit.Framework; namespace DbExtensions.Tests.Querying { using static TestUtil; [TestFixture] public class SqlSetBehaviorForSqlServer { readonly Database db = MockDatabase("Microsoft.Data.SqlClient"); [Test] public void Use_Parameter_On_Skip() { var query = db.FromQuery($"SELECT 1") .Skip(1) .GetDefiningQuery(); Assert.AreEqual(1, query.ParameterValues.Count); } [Test] public void Use_Parameter_On_Take() { var query = db.FromQuery($"SELECT 1") .Take(1) .GetDefiningQuery(); Assert.AreEqual(1, query.ParameterValues.Count); } [Test] public void Use_Parameter_On_Skip_And_Take() { var query = db.FromQuery($"SELECT 1") .Skip(1) .Take(1) .GetDefiningQuery(); Assert.AreEqual(2, query.ParameterValues.Count); } } } ================================================ FILE: tests/DbExtensions.Tests/Querying/SqlTableBehavior.cs ================================================ using System.Collections.ObjectModel; using NUnit.Framework; namespace DbExtensions.Tests.Querying { using static TestUtil; [TestFixture] public class SqlTableBehavior { [Test] public void Dont_Use_Subqueries_When_Methods_Are_Called_In_Order() { var db = MockDatabase(); SqlSet set = db.Table() .Where("UnitsInStock > 0") .Skip(0) .Take(5); SqlBuilder expected = SQL .SELECT(db.QuoteIdentifier("Id")) .FROM(db.QuoteIdentifier("Product")) .WHERE("UnitsInStock > 0") .LIMIT(5) .OFFSET(0); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Can_Use_Multipart_Identifier() { var db = MockDatabase("Microsoft.Data.SqlClient"); SqlSet set = db.Table(); SqlBuilder expected = SQL .SELECT("[ProductID], [ProductName]") .FROM("[dbo].[Products]"); Assert.IsTrue(SqlEquals(set, expected)); } [Test] public void Can_Update_Assigned_Key() { var db = RealDatabase(); var table = db.Table(); string originalId = "FISSA"; string newId = "FOO"; using (var tx = db.EnsureInTransaction()) { var cust1 = table.Find(originalId); Assert.IsNotNull(cust1); cust1.CustomerID = newId; table.Update(cust1, originalId); Assert.IsTrue(table.ContainsKey(newId)); Assert.IsFalse(table.ContainsKey(originalId)); tx.Rollback(); } } [Test] public void Can_Refresh() { var db = RealDatabase(); var table = db.Table(); using (var tx = db.EnsureInTransaction()) { var entity = new SqlTable.Refresh.Product { ProductName = "Foo", Discontinued = false, }; table.Add(entity); var id = entity.ProductID; Assert.AreNotEqual(0, id); entity.ProductName = "Bar"; entity.Discontinued = true; table.Refresh(entity); Assert.AreEqual(id, entity.ProductID); Assert.AreEqual("Foo", entity.ProductName); Assert.AreEqual(false, entity.Discontinued); tx.Rollback(); } } [Test] public void InsertOneToMany_Descendants() { var db = RealDatabase(); var table = db.Table(); using (var tx = db.EnsureInTransaction()) { var lastTerritory = db.Table() .OrderBy("TerritoryID DESC") .First(); var entity = new SqlTable.InsertOneToManyDescendants.Region { RegionID = 9999, RegionDescription = "foo", Territories = { new SqlTable.InsertOneToManyDescendants.Territory { TerritoryID = lastTerritory.TerritoryID + 1000, TerritoryDescription = "foo" }, new SqlTable.InsertOneToManyDescendants.Territory { TerritoryID = lastTerritory.TerritoryID + 1001, TerritoryDescription = "foo", EmployeeTerritories = { new SqlTable.InsertOneToManyDescendants.EmployeeTerritory { EmployeeID = 1 } } }, } }; table.Add(entity); tx.Rollback(); } } } namespace SqlTable { namespace Model1 { [Table] public class Product { [Column] public int Id { get; set; } } } namespace Model2 { [Table(Name = "[dbo].[Products]")] public class Product { [Column(IsPrimaryKey = true)] public int ProductID { get; set; } [Column] public string ProductName { get; set; } } } namespace Model3 { [Table(Name = "Customers")] public class Customer { [Column(IsPrimaryKey = true)] public string CustomerID { get; set; } [Column] public string CompanyName { get; set; } } } namespace Refresh { [Table(Name = "Products")] public class Product { [Column(IsPrimaryKey = true, IsDbGenerated = true)] public int ProductID { get; set; } [Column] public string ProductName { get; set; } [Column] public bool Discontinued { get; set; } } } namespace InsertOneToManyDescendants { [Table(Name = "Region")] public class Region { [Column(IsPrimaryKey = true)] public int RegionID { get; set; } [Column] public string RegionDescription { get; set; } [Association(OtherKey = nameof(Territory.RegionID))] public Collection Territories { get; } = new(); } [Table(Name = "Territories")] public class Territory { [Column(IsPrimaryKey = true)] public string TerritoryID { get; set; } [Column] public string TerritoryDescription { get; set; } [Column] public int RegionID { get; set; } [Association(OtherKey = nameof(EmployeeTerritory.TerritoryID))] public Collection EmployeeTerritories { get; } = new(); } [Table(Name = "EmployeeTerritories")] public class EmployeeTerritory { [Column(IsPrimaryKey = true)] public int EmployeeID { get; set; } [Column(IsPrimaryKey = true)] public string TerritoryID { get; set; } } } } } ================================================ FILE: tests/DbExtensions.Tests/TestUtil.cs ================================================ using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.SQLite; using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Moq; using Moq.Protected; namespace DbExtensions.Tests; static class TestUtil { public static Database MockDatabase(string providerInvariantName = "MySql.Data.MySqlClient") => MockDatabaseImpl(providerInvariantName).Object; static Mock MockDatabaseImpl(string providerInvariantName) { var mockConn = new Mock(); var mockDb = new Mock(mockConn.Object, providerInvariantName) { CallBase = true }; return mockDb; } public static Database MockQuery(params IEnumerable>[] data) { var reader = new TestDataReader(data .Select(p => p as KeyValuePair[] ?? p.ToArray()) .ToArray()); var mockDb = MockDatabaseImpl("MySql.Data.MySqlClient"); SetupReader(mockDb, reader); return mockDb.Object; } public static void SetupReader(Mock mockDb, DbDataReader reader, string commandText = null) { mockDb.Setup(db => db.CreateCommand(It.IsAny())) .Returns(() => { var command = new Mock(); command.SetupProperty(p => p.CommandText, commandText); var commandProt = command.Protected(); commandProt.Setup("DbConnection") .Returns(mockDb.Object.Connection); commandProt.Setup("ExecuteDbDataReader", It.IsAny()) .Returns(reader); commandProt.Setup>("ExecuteDbDataReaderAsync", It.IsAny(), It.IsAny()) .Returns(Task.FromResult(reader)); return command.Object; }); } public static Database RealDatabase() { var builder = new SQLiteConnectionStringBuilder { DataSource = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\..\..\samples\App\bin\Debug\net8.0\Northwind\Northwind.sl3")), FailIfMissing = true }; var conn = new SQLiteConnection(builder.ToString()); var db = new Database(conn); #if DEBUG db.Configuration.Log = Console.Out; #endif return db; } public static bool SqlEquals(SqlSet set, SqlBuilder query) => String.Equals(Regex.Replace(set.ToString(), "dbex_set[0-9]+", "_"), query.ToString(), StringComparison.Ordinal); } class TestDataReader : DbDataReader { readonly KeyValuePair[][] _data; KeyValuePair[] _row; int _rowIndex; public override object this[int i] => _row[i].Value; public override object this[string name] => _row[GetOrdinal(name)].Value; public override int Depth => throw new NotImplementedException(); public override int FieldCount => _row.Length; public override bool HasRows => _data.Length > 0; public override bool IsClosed => false; public override int RecordsAffected => -1; public TestDataReader(params KeyValuePair[][] data) { _data = data; } public override IEnumerator GetEnumerator() => throw new NotImplementedException(); public override bool GetBoolean(int i) => (bool)this[i]; public override byte GetByte(int i) => (byte)this[i]; public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) => throw new NotImplementedException(); public override char GetChar(int i) => (char)this[i]; public override long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) => throw new NotImplementedException(); public override string GetDataTypeName(int i) => throw new NotImplementedException(); public override DateTime GetDateTime(int i) => (DateTime)this[i]; public override decimal GetDecimal(int i) => (decimal)this[i]; public override double GetDouble(int i) => (double)this[i]; public override Type GetFieldType(int i) => throw new NotImplementedException(); public override float GetFloat(int i) => (float)this[i]; public override Guid GetGuid(int i) => (Guid)this[i]; public override short GetInt16(int i) => (short)this[i]; public override int GetInt32(int i) => (int)this[i]; public override long GetInt64(int i) => (long)this[i]; public override string GetName(int i) => _row[i].Key; public override int GetOrdinal(string name) => _row.Select((p, i) => new { p, i }) .Where(p => p.p.Key == name) .Select(p => p.i) .DefaultIfEmpty(-1) .First(); public override string GetString(int i) => (string)this[i]; public override object GetValue(int i) => this[i]; public override int GetValues(object[] values) => throw new NotImplementedException(); public override bool IsDBNull(int i) => this[i] is null; public override bool NextResult() => throw new NotImplementedException(); public override bool Read() { if (_data.Length > _rowIndex) { _row = _data[_rowIndex]; _rowIndex++; return true; } return false; } }