Skip to content

Commit 745484d

Browse files
committed
WIP: Support for DbBatch
1 parent 1a960b0 commit 745484d

20 files changed

+606
-21
lines changed

src/NHibernate.Test/Ado/BatcherFixture.cs

+20-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,18 @@
44

55
namespace NHibernate.Test.Ado
66
{
7-
[TestFixture]
7+
#if NET6_0_OR_GREATER
8+
[TestFixture(true)]
9+
#endif
10+
[TestFixture(false)]
811
public class BatcherFixture: TestCase
912
{
13+
private readonly bool _useDbBatch;
14+
15+
public BatcherFixture(bool useDbBatch)
16+
{
17+
_useDbBatch = useDbBatch;
18+
}
1019
protected override string MappingsAssembly
1120
{
1221
get { return "NHibernate.Test"; }
@@ -22,10 +31,20 @@ protected override void Configure(Configuration configuration)
2231
configuration.SetProperty(Environment.FormatSql, "true");
2332
configuration.SetProperty(Environment.GenerateStatistics, "true");
2433
configuration.SetProperty(Environment.BatchSize, "10");
34+
if (_useDbBatch)
35+
{
36+
configuration.SetProperty("usedbbatch", "true");
37+
}
2538
}
2639

2740
protected override bool AppliesTo(Engine.ISessionFactoryImplementor factory)
2841
{
42+
#if NET6_0_OR_GREATER
43+
if (_useDbBatch)
44+
{
45+
return factory.Settings.BatcherFactory is DbBatchBatcherFactory;
46+
}
47+
#endif
2948
return !(factory.Settings.BatcherFactory is NonBatchingBatcherFactory);
3049
}
3150

src/NHibernate.Test/Async/Ado/BatcherFixture.cs

+20-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@ namespace NHibernate.Test.Ado
1616
{
1717
using System.Threading.Tasks;
1818
using System.Threading;
19-
[TestFixture]
19+
#if NET6_0_OR_GREATER
20+
[TestFixture(true)]
21+
#endif
22+
[TestFixture(false)]
2023
public class BatcherFixtureAsync: TestCase
2124
{
25+
private readonly bool _useDbBatch;
26+
27+
public BatcherFixtureAsync(bool useDbBatch)
28+
{
29+
_useDbBatch = useDbBatch;
30+
}
2231
protected override string MappingsAssembly
2332
{
2433
get { return "NHibernate.Test"; }
@@ -34,10 +43,20 @@ protected override void Configure(Configuration configuration)
3443
configuration.SetProperty(Environment.FormatSql, "true");
3544
configuration.SetProperty(Environment.GenerateStatistics, "true");
3645
configuration.SetProperty(Environment.BatchSize, "10");
46+
if (_useDbBatch)
47+
{
48+
configuration.SetProperty("usedbbatch", "true");
49+
}
3750
}
3851

3952
protected override bool AppliesTo(Engine.ISessionFactoryImplementor factory)
4053
{
54+
#if NET6_0_OR_GREATER
55+
if (_useDbBatch)
56+
{
57+
return factory.Settings.BatcherFactory is DbBatchBatcherFactory;
58+
}
59+
#endif
4160
return !(factory.Settings.BatcherFactory is NonBatchingBatcherFactory);
4261
}
4362

src/NHibernate.Test/NHibernate.Test.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
<ItemGroup>
6363
<PackageReference Include="log4net" Version="2.0.15" />
6464
<PackageReference Include="Microsoft.AspNetCore.OData" Version="7.7.0" />
65-
<PackageReference Include="Microsoft.Data.SqlClient" Version="3.1.3" />
65+
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0-preview4.23342.2" />
6666
<PackageReference Include="NHibernate.Caches.CoreDistributedCache.Memory" Version="5.9.0" />
6767
<PackageReference Include="NHibernate.Caches.Util.JsonSerializer" Version="5.9.0" />
6868
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.117" />

src/NHibernate/AdoNet/AbstractBatcher.cs

+40
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using NHibernate.SqlTypes;
1313
using NHibernate.Util;
1414
using NHibernate.AdoNet.Util;
15+
using System.Linq;
1516

1617
namespace NHibernate.AdoNet
1718
{
@@ -135,6 +136,45 @@ protected void Prepare(DbCommand cmd)
135136
}
136137
}
137138

139+
#if NET6_0_OR_GREATER
140+
/// <summary>
141+
/// Prepares the <see cref="DbBatch"/> for execution in the database.
142+
/// </summary>
143+
/// <remarks>
144+
/// This takes care of hooking the <see cref="DbBatch"/> up to an <see cref="DbConnection"/>
145+
/// and <see cref="DbTransaction"/> if one exists. It will call <c>Prepare</c> if the Driver
146+
/// supports preparing batches.
147+
/// </remarks>
148+
protected void Prepare(DbBatch batch)
149+
{
150+
try
151+
{
152+
var sessionConnection = _connectionManager.GetConnection();
153+
154+
if (batch.Connection != null)
155+
{
156+
// make sure the commands connection is the same as the Sessions connection
157+
// these can be different when the session is disconnected and then reconnected
158+
if (batch.Connection != sessionConnection)
159+
{
160+
batch.Connection = sessionConnection;
161+
}
162+
}
163+
else
164+
{
165+
batch.Connection = sessionConnection;
166+
}
167+
168+
_connectionManager.EnlistInTransaction(batch);
169+
(Driver as IDriverWithBatchSupport).PrepareBatch(batch);
170+
}
171+
catch (InvalidOperationException ioe)
172+
{
173+
throw new ADOException("While preparing " + string.Join(Environment.NewLine, batch.BatchCommands.Select(x=>x.CommandText)) + " an error occurred", ioe);
174+
}
175+
}
176+
#endif
177+
138178
public virtual DbCommand PrepareBatchCommand(CommandType type, SqlString sql, SqlType[] parameterTypes)
139179
{
140180
if (sql.Equals(_batchCommandSql) && ArrayHelper.ArrayEquals(parameterTypes, _batchCommandParameterTypes))

src/NHibernate/AdoNet/ConnectionManager.cs

+24
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,30 @@ public void EnlistInTransaction(DbCommand command)
514514
}
515515
}
516516

517+
#if NET6_0_OR_GREATER
518+
/// <summary>
519+
/// Enlist a batch in the current transaction, if any.
520+
/// </summary>
521+
/// <param name="batch">The batch to enlist.</param>
522+
public void EnlistInTransaction(DbBatch batch)
523+
{
524+
if (batch == null)
525+
throw new ArgumentNullException(nameof(batch));
526+
527+
if (_transaction is ITransactionWithBatchSupport transactionWithBatch)
528+
{
529+
transactionWithBatch.Enlist(batch);
530+
return;
531+
}
532+
533+
if (batch.Transaction != null)
534+
{
535+
_log.Warn("set a nonnull DbCommand.Transaction to null because the Session had no Transaction");
536+
batch.Transaction = null;
537+
}
538+
}
539+
#endif
540+
517541
/// <summary>
518542
/// Enlist the connection into provided transaction if the connection should be enlisted.
519543
/// Do nothing in case an explicit transaction is ongoing.

0 commit comments

Comments
 (0)