diff --git a/.github/workflows/slo.yml b/.github/workflows/slo.yml
index cf4fe1a5..621d4be7 100644
--- a/.github/workflows/slo.yml
+++ b/.github/workflows/slo.yml
@@ -20,6 +20,7 @@ jobs:
- AdoNet
- Dapper
- EF
+ - Linq2db.Slo
include:
- workload: AdoNet
read_rps: 1000
@@ -30,7 +31,10 @@ jobs:
- workload: EF
read_rps: 1000
write_rps: 100
-
+ - workload: Linq2db.Slo
+ read_rps: 1000
+ write_rps: 100
+
concurrency:
group: slo-${{ github.ref }}-${{ matrix.workload }}
cancel-in-progress: true
diff --git a/slo/src/Linq2db.Slo/Linq2db.Slo.csproj b/slo/src/Linq2db.Slo/Linq2db.Slo.csproj
new file mode 100644
index 00000000..e5c41c89
--- /dev/null
+++ b/slo/src/Linq2db.Slo/Linq2db.Slo.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+ Linq2db
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/slo/src/Linq2db.Slo/Program.cs b/slo/src/Linq2db.Slo/Program.cs
new file mode 100644
index 00000000..2fdddd57
--- /dev/null
+++ b/slo/src/Linq2db.Slo/Program.cs
@@ -0,0 +1,4 @@
+using Internal;
+using Linq2db;
+
+await Cli.Run(new SloTableContext(), args);
\ No newline at end of file
diff --git a/slo/src/Linq2db.Slo/SloTableContext.cs b/slo/src/Linq2db.Slo/SloTableContext.cs
new file mode 100644
index 00000000..ca434151
--- /dev/null
+++ b/slo/src/Linq2db.Slo/SloTableContext.cs
@@ -0,0 +1,105 @@
+using Internal;
+using Linq2db.Ydb;
+using Linq2db.Ydb.Internal;
+using LinqToDB;
+using LinqToDB.Async;
+using LinqToDB.Data;
+using LinqToDB.Mapping;
+
+namespace Linq2db;
+
+public sealed class SloTableContext : SloTableContext
+{
+ protected override string Job => "Linq2db";
+
+ static SloTableContext()
+ {
+ YdbSdkRetryPolicyRegistration.UseGloballyWithIdempotence();
+ DataConnection.AddProviderDetector(YdbTools.ProviderDetector);
+ }
+
+ public sealed class Linq2dbClient(string connectionString)
+ {
+ public DataConnection Open()
+ => new(new DataOptions().UseConnectionString("YDB", connectionString));
+ }
+
+ protected override Linq2dbClient CreateClient(Config config) => new(config.ConnectionString);
+
+ protected override async Task Create(Linq2dbClient client, int operationTimeout)
+ {
+ await using var db = client.Open();
+ db.CommandTimeout = operationTimeout;
+
+ await db.ExecuteAsync($@"
+ CREATE TABLE `{SloTable.Name}` (
+ Guid Uuid,
+ Id Int32,
+ PayloadStr Text,
+ PayloadDouble Double,
+ PayloadTimestamp Timestamp,
+ PRIMARY KEY (Guid, Id)
+ )");
+
+ await db.ExecuteAsync(SloTable.Options);
+ }
+
+ protected override async Task Save(Linq2dbClient client, SloTable sloTable, int writeTimeout)
+ {
+ await using var db = client.Open();
+ db.CommandTimeout = writeTimeout;
+
+ var sql = $@"
+UPSERT INTO `{SloTable.Name}` (Guid, Id, PayloadStr, PayloadDouble, PayloadTimestamp)
+VALUES (@Guid, @Id, @PayloadStr, @PayloadDouble, @PayloadTimestamp);";
+
+ var affected = await db.ExecuteAsync(
+ sql,
+ new DataParameter("Guid", sloTable.Guid, DataType.Guid),
+ new DataParameter("Id", sloTable.Id, DataType.Int32),
+ new DataParameter("PayloadStr", sloTable.PayloadStr, DataType.NVarChar),
+ new DataParameter("PayloadDouble", sloTable.PayloadDouble, DataType.Double),
+ new DataParameter("PayloadTimestamp", sloTable.PayloadTimestamp, DataType.DateTime2)
+ );
+
+ return affected > 0 ? affected : 1;
+ }
+
+ protected override async Task