### Install SqlArtisan.ArrayBind
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/guides/oracle-array-bind.md
Install the pre-release package via the .NET CLI.
```bash
dotnet add package SqlArtisan.ArrayBind --prerelease
```
--------------------------------
### Install SqlArtisan Packages
Source: https://github.com/h-tacayama/sqlartisan/blob/main/README.md
Use the dotnet CLI to install the core library and optional extensions.
```bash
dotnet add package SqlArtisan --prerelease # core query builder
dotnet add package SqlArtisan.Dapper --prerelease # optional: Dapper execution
dotnet add package SqlArtisan.ArrayBind --prerelease # optional: Oracle array-bind execution
```
--------------------------------
### Install SqlArtisan.TableClassGen
Source: https://github.com/h-tacayama/sqlartisan/blob/main/src/SqlArtisan.TableClassGen/README.md
Install the tool as a global .NET tool using the --prerelease flag.
```bash
dotnet tool install --global SqlArtisan.TableClassGen --prerelease
```
--------------------------------
### Install SqlArtisan Packages
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/guides/dapper-quickstart.md
Use the .NET CLI to add the core query builder and Dapper execution extensions to your project.
```bash
dotnet add package SqlArtisan --prerelease # core query builder
dotnet add package SqlArtisan.Dapper --prerelease # Dapper execution extensions
```
--------------------------------
### Demonstrate configuration override behavior
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Example showing how the syntax family key overrides legacy keys, potentially causing coverage loss.
```ini
sqlartisan_target_dbms = postgresql
sqlartisan_syntax_oracle = any
```
--------------------------------
### Generate Table Classes
Source: https://github.com/h-tacayama/sqlartisan/blob/main/src/SqlArtisan.TableClassGen/README.md
Example command to generate table classes for a PostgreSQL database.
```bash
export SQLARTISAN_DB_PASSWORD=...
sa-tableclassgen \
--dbms postgresql --host localhost --database myservice --schema myschema \
--user myuser \
--namespace MyApp.Tables --output src/MyApp/Tables
```
--------------------------------
### Generate Table Classes
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/guides/dapper-quickstart.md
Install and run the global tool to automatically generate table classes from an existing database schema.
```bash
dotnet tool install --global SqlArtisan.TableClassGen --prerelease
sa-tableclassgen # interactive: connection info → namespace → output directory
```
--------------------------------
### Example of dialect-specific build warning
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/guides/ai-assistants.md
Demonstrates how the analyzer flags unsupported constructs when the dialect is restricted.
```csharp
// sqlartisan_syntax_mysql = any
var g = Rollup(t.Code, t.Name);
// warning SQLA0100: 'Rollup' is not supported on MySQL. ...
```
--------------------------------
### Verbose Generation Output
Source: https://github.com/h-tacayama/sqlartisan/blob/main/src/SqlArtisan.TableClassGen/README.md
Example output when running the generator with the --verbose flag.
```text
$ sa-tableclassgen --config tablegen.json --verbose
unchanged src/MyApp/Tables/CustomersTable.cs
modified src/MyApp/Tables/OrdersTable.cs
Generated 1 of 2 table classes in src/MyApp/Tables
```
--------------------------------
### Detecting Schema Drift
Source: https://github.com/h-tacayama/sqlartisan/blob/main/src/SqlArtisan.TableClassGen/README.md
Example output when running the generator with the --check flag to identify schema changes.
```text
$ sa-tableclassgen --config tablegen.json --check
Drift detected against src/MyApp/Tables (3 tables):
added audit_log
modified employees
+ email
removed DepartmentsTable.cs
Regenerate the affected tables by re-running with:
--fix --tables audit_log,employees
These files have no table in the database and are left untouched:
src/MyApp/Tables/DepartmentsTable.cs
```
--------------------------------
### Example of SQLA0100 diagnostic reporting
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Demonstrates how SQLA0100 aggregates unsupported construct warnings across multiple configured dialects.
```csharp
// sqlartisan_syntax_mysql = any
// sqlartisan_syntax_oracle = any
// sqlartisan_syntax_sqlite = any
var g = Rollup(t.Code, t.Name);
// warning SQLA0100: 'Rollup' is not supported on MySQL and SQLite. Set
// 'sqlartisan_construct_rollup = supported' in .editorconfig if your
// engine version supports it.
```
--------------------------------
### Generated C# Table Class Example
Source: https://github.com/h-tacayama/sqlartisan/blob/main/src/SqlArtisan.TableClassGen/README.md
Example of a C# class generated by SqlArtisan for a 'users' table, inheriting from DbTableBase and including column metadata.
```csharp
//
#nullable enable
using SqlArtisan;
namespace MyApp.Tables;
internal sealed class UsersTable : DbTableBase
{
public UsersTable(string tableAlias = "") : base("users", tableAlias)
{
Id = new DbColumn(this, "id");
Name = new DbColumn(this, "name");
CreatedAt = new DbColumn(this, "created_at");
}
[DbColumnMetadata(Nullable = false, HasDefault = true, Indexed = true, TypeCategory = DbTypeCategory.Numeric)]
public DbColumn Id { get; }
[DbColumnMetadata(Nullable = false, HasDefault = false, Indexed = true, TypeCategory = DbTypeCategory.Text)]
public DbColumn Name { get; }
[DbColumnMetadata(Nullable = true, HasDefault = false, Indexed = false, TypeCategory = DbTypeCategory.Temporal)]
public DbColumn CreatedAt { get; }
}
```
--------------------------------
### Boolean Comparison Patterns
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Examples of idiomatic boolean comparisons in T-SQL and MySQL that trigger or avoid schema-aware warnings.
```sql
WHERE is_active = 1
```
```sql
Cast(...)
```
```sql
new DbTable("t").Column("x")
```
```sql
Select(...)
```
```sql
.Where(s.Ref.IsNotNull)
```
--------------------------------
### Example of inconsistent identifier and literal handling
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/adr/0016-text-position-policy.md
Demonstrates the behavior of various identifier and literal positions when handling raw caller strings.
```sql
SELECT id "x" ; DROP TABLE t --", CAST(id AS INT) ; DROP TABLE t --),
NEXTVAL('s''); DROP TABLE t --') FROM users; DROP TABLE t --
```
--------------------------------
### Define column metadata
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Example of how SqlArtisan records column metadata for the analyzer.
```csharp
[DbColumnMetadata(Nullable = false, HasDefault = false, TypeCategory = DbTypeCategory.Text)]
public DbColumn Code { get; }
```
--------------------------------
### Triggering SQLA0100 Diagnostic
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Example of a construct triggering a dialect support warning.
```csharp
using static SqlArtisan.Sql;
// sqlartisan_syntax_mysql = any
var g = Rollup(t.Code, t.Name);
// warning SQLA0100: 'Rollup' is not supported on MySQL. Set
// 'sqlartisan_construct_rollup = supported' in .editorconfig if your
// engine version supports it.
```
--------------------------------
### Build and test the SqlArtisan solution
Source: https://github.com/h-tacayama/sqlartisan/blob/main/CLAUDE.md
Standard commands to restore dependencies, build the solution, run unit tests, and verify code formatting.
```bash
dotnet restore
dotnet build SqlArtisan.sln
dotnet test tests/SqlArtisan.Tests # unit tests (xUnit)
dotnet test tests/SqlArtisan.Analyzers.Tests # analyzer tests
dotnet test tests/SqlArtisan.TableClassGen.Tests # TableClassGen tests
dotnet format SqlArtisan.sln --verify-no-changes # .editorconfig style gate (CI enforces this)
```
--------------------------------
### Run with Configuration File
Source: https://github.com/h-tacayama/sqlartisan/blob/main/src/SqlArtisan.TableClassGen/README.md
Execute the generator using a previously defined JSON configuration file.
```bash
sa-tableclassgen --config tablegen.json
```
--------------------------------
### Configure and detect COUNT nullability warning (SQLA0203)
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Shows how to enable the SQLA0203 warning via configuration and the resulting diagnostic for nullable column counts.
```ini
[*.cs]
dotnet_diagnostic.SQLA0203.severity = suggestion
```
```csharp
var sql = Select(Count(t.Note)).From(t).Build(); // t.Note is nullable
// info SQLA0203: 'Note' is nullable, so this COUNT skips its NULL rows.
// Use Count(Asterisk) to count rows.
```
--------------------------------
### Run SqlArtisan benchmarks
Source: https://github.com/h-tacayama/sqlartisan/blob/main/tests/SqlArtisan.Benchmark/README.md
Commands to validate and execute benchmarks using the .NET CLI. Release configuration is mandatory for accurate performance measurements.
```bash
P=tests/SqlArtisan.Benchmark
dotnet run --project $P -c Release -- validate # not a measurement
dotnet run --project $P -c Release -- --filter '*SqlBuilderBenchmarks*'
dotnet run --project $P -c Release # pick a suite
```
--------------------------------
### Use Aggregate Functions as Window Functions
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/expressions.md
Demonstrates applying an aggregate function over a partition using the Over() and PartitionBy() methods.
```csharp
UsersTable u = new();
SqlStatement sql =
Select(
u.Id,
u.Salary,
Sum(u.Salary).Over(PartitionBy(u.DepartmentId)).As("dept_total"))
.From(u)
.Build();
// SELECT id, salary,
// SUM(salary) OVER (PARTITION BY department_id) "dept_total"
// FROM users
```
--------------------------------
### Using EXISTS and NOT EXISTS
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/expressions.md
Demonstrates existence checks using subqueries.
```csharp
UsersTable a = new("a");
UsersTable b = new("b");
UsersTable c = new("c");
SqlStatement sql =
Select(a.Name)
.From(a)
.Where(
Exists(Select(b.Id).From(b))
& NotExists(Select(c.Id).From(c)))
.Build();
// SELECT "a".name
// FROM users "a"
// WHERE (EXISTS (SELECT "b".id FROM users "b"))
// AND (NOT EXISTS (SELECT "c".id FROM users "c"))
```
--------------------------------
### Configuration File Format
Source: https://github.com/h-tacayama/sqlartisan/blob/main/src/SqlArtisan.TableClassGen/README.md
JSON configuration file structure for defining database connection and generation settings.
```json
{
"dbms": "postgresql",
"host": "localhost",
"database": "myservice",
"schema": "myschema",
"user": "myuser",
"namespace": "MyApp.Tables",
"output": "src/MyApp/Tables"
}
```
--------------------------------
### Triggering SQLA0300 with an unaliased target
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Example of a correlated DELETE statement using an unaliased table that triggers the SQLA0300 warning.
```csharp
// sqlartisan_syntax_postgresql = any
UsersTable u = new();
OrdersTable o = new("o");
var q = DeleteFrom(u)
.Where(Exists(Select(o.Id).From(o).Where(o.UserId == u.Id)));
// warning SQLA0300: The target of a correlated UPDATE or DELETE must be aliased
```
--------------------------------
### Oracle Extract Datepart Validation
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Example of SQLA0104 triggering a warning when using an unsupported Epoch datepart with Extract on Oracle.
```csharp
// sqlartisan_syntax_oracle = any
var q = Select(Extract(DateTimePart.Epoch, u.CreatedAt)).From(u);
// warning SQLA0104: 'Epoch' is not a valid datepart for 'Extract' on Oracle
```
--------------------------------
### Trigger SQLA0101 warning in C#
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Example of using a construct that triggers a version warning based on the configured engine version.
```csharp
using static SqlArtisan.Sql;
var g = Datetrunc(DateTimePart.Day, "created_at");
// warning SQLA0101: 'Datetrunc' requires SQL Server 2022+ but the declared
// target version is 2019. Set 'sqlartisan_construct_datetrunc = supported'
// in .editorconfig if your engine supports it.
```
--------------------------------
### Verify SQL and parameters with unit tests
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/guides/dapper-quickstart.md
Use the Build() method to generate a SQL statement for a specific DBMS and assert the resulting text and parameter values.
```csharp
[Fact]
public void ActiveUsersQuery_CorrectSql()
{
UsersTable u = new("u");
SqlStatement sql =
Select(u.Id, u.Name).From(u).Where(u.Id > 100).Build(Dbms.PostgreSql);
Assert.Equal(
"SELECT \"u\".id, \"u\".name FROM users \"u\" WHERE \"u\".id > :0",
sql.Text);
Assert.Equal(100, sql.Parameters.Get(":0"));
}
```
--------------------------------
### Perform SQLite FTS5 Search
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/expressions.md
Uses Match against an FTS5 virtual table. Requires an FTS5 virtual table setup.
```csharp
DbTable fts = new("posts_fts");
SqlStatement sql =
Select(fts.Column("title"))
.From(fts)
.Where(Match(fts, "database"))
.Build(Dbms.Sqlite);
// SELECT title FROM posts_fts
// WHERE posts_fts MATCH :0
```
--------------------------------
### Command Line Usage
Source: https://github.com/h-tacayama/sqlartisan/blob/main/src/SqlArtisan.TableClassGen/README.md
Common command line patterns for generating, checking, and fixing table classes.
```bash
sa-tableclassgen [options] # generate table classes
sa-tableclassgen --check [options] # report drift, write nothing
sa-tableclassgen --fix [options] # regenerate the drifted tables, report them
sa-tableclassgen # interactive prompts (terminal only)
```
--------------------------------
### SQL Server Datetrunc Datepart Validation
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Example of SQLA0104 triggering a warning when using an unsupported Weekday datepart with Datetrunc on SQL Server.
```csharp
// sqlartisan_syntax_sqlserver = any
var q = Select(Datetrunc(DateTimePart.Weekday, u.CreatedAt)).From(u);
// warning SQLA0104: 'Weekday' is not a valid datepart for 'Datetrunc' on SQL Server
```
--------------------------------
### Use any and none for dialect scoping
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Use 'any' to enable a dialect without version constraints and 'none' to explicitly exclude a dialect in specific file paths.
```ini
# repo-wide: this product ships against all five
[*.cs]
sqlartisan_syntax_mysql = any
sqlartisan_syntax_oracle = any
sqlartisan_syntax_postgresql = any
sqlartisan_syntax_sqlite = any
sqlartisan_syntax_sqlserver = any
# except this area, which never runs on the embedded engine
[src/Reporting/**.cs]
sqlartisan_syntax_sqlite = none
```
--------------------------------
### Promote analyzer warnings to build errors
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/guides/ai-assistants.md
Configure the build process to treat SQLA0100 violations as errors to prevent merging incorrect dialect code.
```ini
dotnet_diagnostic.SQLA0100.severity = error
```
--------------------------------
### Create a paginated list with a reusable query
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/cookbook.md
Wrap a builder chain in a function to generate fresh instances for each call, as builder chains are single-use.
```csharp
Customer c = new("c");
Order o = new("o");
SqlStatement Page(int offset) =>
Select(c.CustomerId, c.FirstName, c.LastName, o.OrderId, o.TotalAmount)
.From(c)
.InnerJoin(o).On(c.CustomerId == o.CustomerId)
.Where(o.Status == "shipped")
.OrderBy(o.OrderedAt.Desc, o.OrderId)
.Limit(20).Offset(offset)
.Build();
SqlStatement page1 = Page(0);
SqlStatement page2 = Page(20);
```
--------------------------------
### Configure Default DBMS
Source: https://github.com/h-tacayama/sqlartisan/blob/main/README.md
Set the global default DBMS at application startup to avoid passing it in every Build() call. Note that SqlArtisanConfig is not thread-safe.
```csharp
// At application startup
SqlArtisanConfig.SetDefaultDbms(Dbms.SqlServer);
// Now, Build() without arguments will generate SQL Server-compatible SQL
SqlStatement sql = Select(u.Name).From(u).Build();
```
--------------------------------
### Define Customer and Order table classes
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/cookbook.md
Implements the database schema for customers and orders by inheriting from DbTableBase and defining columns.
```csharp
internal sealed class Customer : DbTableBase
{
public Customer(string alias = "") : base("customer", alias)
{
CustomerId = new DbColumn(this, "customer_id");
FirstName = new DbColumn(this, "first_name");
LastName = new DbColumn(this, "last_name");
Email = new DbColumn(this, "email");
Region = new DbColumn(this, "region");
CreatedAt = new DbColumn(this, "created_at");
}
public DbColumn CustomerId { get; }
public DbColumn FirstName { get; }
public DbColumn LastName { get; }
public DbColumn Email { get; }
public DbColumn Region { get; }
public DbColumn CreatedAt { get; }
}
internal sealed class Order : DbTableBase
{
public Order(string alias = "") : base("orders", alias)
{
OrderId = new DbColumn(this, "order_id");
CustomerId = new DbColumn(this, "customer_id");
OrderedAt = new DbColumn(this, "ordered_at");
Status = new DbColumn(this, "status");
TotalAmount = new DbColumn(this, "total_amount");
}
public DbColumn OrderId { get; }
public DbColumn CustomerId { get; }
public DbColumn OrderedAt { get; }
public DbColumn Status { get; }
public DbColumn TotalAmount { get; }
}
```
--------------------------------
### Apply Windowed Percentile Functions
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/expressions.md
Shows the windowed form of PercentileCont using Over() with and without partitioning.
```csharp
PercentileCont(0.5).WithinGroup(OrderBy(u.Salary)).Over()
// PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary) OVER ()
PercentileCont(0.5).WithinGroup(OrderBy(u.Salary)).Over(PartitionBy(u.DepartmentId))
// PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary) OVER (PARTITION BY department_id)
```
--------------------------------
### Manual SQL Generation
Source: https://github.com/h-tacayama/sqlartisan/blob/main/README.md
Use the Build method to generate raw SQL strings and parameters for non-Dapper scenarios.
```csharp
SqlStatement sql = Select(u.Id, u.Name).From(u).Where(u.Id == 10).Build();
// sql.Text => "SELECT id, name FROM users WHERE id = :0"
// sql.Parameters => ":0" is 10
```
--------------------------------
### Migrate legacy target keys to syntax family
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Replace deprecated legacy keys with the new syntax family key format.
```diff
-sqlartisan_target_dbms = postgresql
-sqlartisan_target_version = 16
+sqlartisan_syntax_postgresql = 16
```
--------------------------------
### Build and Execute Queries with Dapper
Source: https://github.com/h-tacayama/sqlartisan/blob/main/README.md
Construct a query using the fluent API and execute it using Dapper integration.
```csharp
using SqlArtisan;
using SqlArtisan.Dapper;
using static SqlArtisan.Sql;
// ...
UsersTable u = new();
ISqlBuilder sql =
Select(u.Id, u.Name, u.CreatedAt)
.From(u)
.Where(u.Id > 0 & u.Name.Like("A%"))
.OrderBy(u.Id);
// Dapper: Set true to map snake_case columns to PascalCase/camelCase C# members.
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
// 'connection' is your IDbConnection. SqlArtisan auto-detects the DBMS
// (MySQL, Oracle, PostgreSQL, SQLite, SQL Server) & applies
// the correct bind-parameter prefix (e.g., ':' or '@').
IEnumerable users = await connection.QueryAsync(sql);
```
--------------------------------
### Enable Analyzer via .editorconfig
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Configure the target dialect and version in your .editorconfig file to enable build-time checks.
```ini
root = true
[*.cs]
sqlartisan_syntax_postgresql = 16 # engine version, or `any` for no version bound
```
--------------------------------
### Enable Analyzer via MSBuild
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Alternatively, use MSBuild properties in your project files or Directory.Build.props to set the target dialect.
```xml
16
```
--------------------------------
### Perform Batch Updates with Array Binding
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/guides/oracle-array-bind.md
Shows how to use ISqlBuilder to perform batch updates or deletes by passing a list of statements to ExecuteArrayBind.
```csharp
List statements = rows.Select(row =>
Update(users).Set(users.Name == row.Name).Where(users.Id == row.Id))
.ToList();
int updated = connection.ExecuteArrayBind(statements, transaction);
```
--------------------------------
### Invoke per-dialect sequence syntax
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/comparison.md
Demonstrates how SqlArtisan exposes engine-specific syntax for sequence operations.
```csharp
Sequence("users_id_seq").Nextval // Oracle: users_id_seq.NEXTVAL
Nextval("users_id_seq") // PostgreSQL: NEXTVAL('users_id_seq')
NextValueFor("users_id_seq") // SQL Server: NEXT VALUE FOR users_id_seq
```
--------------------------------
### Configure multiple dialects in .editorconfig
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Define multiple sqlartisan_syntax keys to validate code against several database engines simultaneously.
```ini
root = true
[*.cs]
sqlartisan_syntax_postgresql = 16
sqlartisan_syntax_oracle = 19
sqlartisan_syntax_sqlite = any
```
--------------------------------
### Implement a Simple CASE Expression
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/expressions.md
Use the Case method with a column reference and multiple When-Then pairs to map specific values to labels.
```csharp
UsersTable u = new();
SqlStatement sql =
Select(
u.Id,
u.Name,
Case(
u.StatusId,
When(1).Then("Active"),
When(2).Then("Inactive"),
When(3).Then("Pending"),
Else("Unknown"))
.As("StatusDescription"))
.From(u)
.Build();
// SELECT id, name,
// CASE status_id
// WHEN :0 THEN :1
// WHEN :2 THEN :3
// WHEN :4 THEN :5
// ELSE :6
// END "StatusDescription"
// FROM users
```
--------------------------------
### Execute Dapper queries with SqlArtisan
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/guides/dapper-quickstart.md
Demonstrates querying and executing updates by passing builder chains directly to Dapper methods. Requires setting Dapper's DefaultTypeMap for snake_case mapping if needed.
```csharp
using SqlArtisan;
using SqlArtisan.Dapper;
using static SqlArtisan.Sql;
// Dapper maps snake_case columns to PascalCase members with this on:
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
UsersTable u = new("u");
IEnumerable users = await connection.QueryAsync(
Select(u.Id, u.Name, u.CreatedAt)
.From(u)
.Where(u.Name.Like("A%"))
.OrderBy(u.Id));
UsersTable w = new();
int affected = await connection.ExecuteAsync(
Update(w).Set(w.Name == "renamed").Where(w.Id == 1));
```
--------------------------------
### Execute Array Bind Operations
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/guides/oracle-array-bind.md
Demonstrates executing batch operations using ExecuteArrayBind or its asynchronous counterpart on an OracleConnection.
```csharp
using SqlArtisan.ArrayBind;
using OracleConnection connection = new(connectionString);
connection.Open();
using OracleTransaction transaction = connection.BeginTransaction();
int inserted = connection.ExecuteArrayBind(statements, transaction);
// or: await connection.ExecuteArrayBindAsync(statements, transaction, cancellationToken);
transaction.Commit();
```
--------------------------------
### Configure Multi-Dialect Syntax in .editorconfig
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/adr/0019-analyzer-multi-dialect-syntax-set.md
Define the target DBMS engines and their respective versions or 'any' status within an .editorconfig file.
```ini
sqlartisan_syntax_postgresql = 16
sqlartisan_syntax_oracle = 19
sqlartisan_syntax_sqlite = any
```
--------------------------------
### Build a SQL query with SqlArtisan
Source: https://github.com/h-tacayama/sqlartisan/blob/main/tests/SqlArtisan.Benchmark/README.md
Demonstrates the fluent API for constructing an INNER JOIN query with aggregation and date filtering.
```csharp
Select(u.Id.As("user_id"), u.Name.As("user_name"), Count(o.Id).As("order_count"))
.From(u)
.InnerJoin(o).On(u.Id == o.UserId)
.Where(o.OrderDate >= new DateTime(2024, 1, 1)
& o.OrderDate < new DateTime(2025, 1, 1))
.GroupBy(u.Id, u.Name)
.OrderBy(Count(o.Id).As("order_count").Desc)
.Build();
```
--------------------------------
### Execute Dapper queries with timeout and cancellation
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/guides/dapper-quickstart.md
Shows how to pass optional commandTimeout and cancellationToken arguments to Dapper extension methods.
```csharp
IEnumerable recent = await connection.QueryAsync(
Select(u.Id, u.Name).From(u).OrderBy(u.Id),
commandTimeout: 30,
cancellationToken: HttpContext.RequestAborted);
```
--------------------------------
### Configure engine version in .editorconfig
Source: https://github.com/h-tacayama/sqlartisan/blob/main/docs/analyzer.md
Set the target SQL Server version to 2019 in the project root.
```ini
root = true
[*.cs]
sqlartisan_syntax_sqlserver = 2019
```