Unverified Commit 651325ae authored by Marc Gravell's avatar Marc Gravell Committed by GitHub

Marc/wrapped async reader (#1278)

* fix #1277 - make sure that the command is disposed at the correct time when using ExecuteReaderAsync; this means pushing it into WrappedReader, which was in turn overdue some love; as part of that, add netcoreapp2.1 target so we can expose the best reader possible

* fix tests - removed MSSQLCLIENT for now
parent 191a1cb8
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<Title>Dapper (Strong Named)</Title> <Title>Dapper (Strong Named)</Title>
<Description>A high performance Micro-ORM supporting SQL Server, MySQL, Sqlite, SqlCE, Firebird etc..</Description> <Description>A high performance Micro-ORM supporting SQL Server, MySQL, Sqlite, SqlCE, Firebird etc..</Description>
<Authors>Sam Saffron;Marc Gravell;Nick Craver</Authors> <Authors>Sam Saffron;Marc Gravell;Nick Craver</Authors>
<TargetFrameworks>net451;netstandard1.3;netstandard2.0</TargetFrameworks> <TargetFrameworks>net451;netstandard1.3;netstandard2.0;netcoreapp2.1</TargetFrameworks>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign> <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
</PropertyGroup> </PropertyGroup>
...@@ -24,6 +24,10 @@ ...@@ -24,6 +24,10 @@
<PackageReference Include="System.Reflection.TypeExtensions" Version="4.4.0" /> <PackageReference Include="System.Reflection.TypeExtensions" Version="4.4.0" />
<!-- it would be nice to use System.Data.Common here, but we need SqlClient for SqlDbType in 1.3, and legacy SqlDataRecord API--> <!-- it would be nice to use System.Data.Common here, but we need SqlClient for SqlDbType in 1.3, and legacy SqlDataRecord API-->
<!--<PackageReference Include="System.Data.Common" Version="4.3.0" />-->
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" /> <PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' "> <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
......
...@@ -11,13 +11,17 @@ namespace Dapper.Tests ...@@ -11,13 +11,17 @@ namespace Dapper.Tests
{ {
[Collection(NonParallelDefinition.Name)] [Collection(NonParallelDefinition.Name)]
public sealed class SystemSqlClientAsyncTests : AsyncTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientAsyncTests : AsyncTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection(NonParallelDefinition.Name)] [Collection(NonParallelDefinition.Name)]
public sealed class MicrosoftSqlClientAsyncTests : AsyncTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientAsyncTests : AsyncTests<MicrosoftSqlClientProvider> { }
#endif
[Collection(NonParallelDefinition.Name)] [Collection(NonParallelDefinition.Name)]
public sealed class SystemSqlClientAsyncQueryCacheTests : AsyncQueryCacheTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientAsyncQueryCacheTests : AsyncQueryCacheTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection(NonParallelDefinition.Name)] [Collection(NonParallelDefinition.Name)]
public sealed class MicrosoftSqlClientAsyncQueryCacheTests : AsyncQueryCacheTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientAsyncQueryCacheTests : AsyncQueryCacheTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class AsyncTests<TProvider> : TestBase<TProvider> where TProvider : SqlServerDatabaseProvider public abstract class AsyncTests<TProvider> : TestBase<TProvider> where TProvider : SqlServerDatabaseProvider
......
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientConstructorTests : ConstructorTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientConstructorTests : ConstructorTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientConstructorTests : ConstructorTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientConstructorTests : ConstructorTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class ConstructorTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class ConstructorTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
......
...@@ -16,6 +16,14 @@ ...@@ -16,6 +16,14 @@
<ItemGroup> <ItemGroup>
<None Remove="Test.DB.sdf" /> <None Remove="Test.DB.sdf" />
</ItemGroup> </ItemGroup>
<!-- these two go together
<PropertyGroup>
<DefineConstants>$(DefineConstants);MSSQLCLIENT</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.SqlClient" Version="1.0.19128.1-Preview" />
</ItemGroup>
-->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Dapper\Dapper.csproj" /> <ProjectReference Include="..\Dapper\Dapper.csproj" />
<ProjectReference Include="..\Dapper.Contrib\Dapper.Contrib.csproj" /> <ProjectReference Include="..\Dapper.Contrib\Dapper.Contrib.csproj" />
...@@ -26,7 +34,6 @@ ...@@ -26,7 +34,6 @@
<PackageReference Include="System.ValueTuple" Version="4.4.0" /> <PackageReference Include="System.ValueTuple" Version="4.4.0" />
<PackageReference Include="xunit" Version="$(xUnitVersion)" /> <PackageReference Include="xunit" Version="$(xUnitVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitVersion)" /> <PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitVersion)" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="1.0.19128.1-Preview" />
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" /> <PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
</ItemGroup> </ItemGroup>
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientDataReaderTests : DataReaderTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientDataReaderTests : DataReaderTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientDataReaderTests : DataReaderTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientDataReaderTests : DataReaderTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class DataReaderTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class DataReaderTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
......
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientDecimalTests : DecimalTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientDecimalTests : DecimalTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientDecimalTests : DecimalTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientDecimalTests : DecimalTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class DecimalTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class DecimalTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientEnumTests : EnumTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientEnumTests : EnumTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientEnumTests : EnumTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientEnumTests : EnumTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class EnumTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class EnumTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientLiteralTests : LiteralTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientLiteralTests : LiteralTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientLiteralTests : LiteralTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientLiteralTests : LiteralTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class LiteralTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class LiteralTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
...@@ -40,7 +40,9 @@ public GenericUriParser(GenericUriParserOptions options) ...@@ -40,7 +40,9 @@ public GenericUriParser(GenericUriParserOptions options)
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientMiscTests : MiscTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientMiscTests : MiscTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientMiscTests : MiscTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientMiscTests : MiscTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class MiscTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class MiscTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientMultiMapTests : MultiMapTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientMultiMapTests : MultiMapTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientMultiMapTests : MultiMapTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientMultiMapTests : MultiMapTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class MultiMapTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class MultiMapTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
...@@ -4,8 +4,10 @@ namespace Dapper.Tests ...@@ -4,8 +4,10 @@ namespace Dapper.Tests
{ {
[Collection(NonParallelDefinition.Name)] [Collection(NonParallelDefinition.Name)]
public sealed class SystemSqlClientNullTests : NullTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientNullTests : NullTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection(NonParallelDefinition.Name)] [Collection(NonParallelDefinition.Name)]
public sealed class MicrosoftSqlClientNullTests : NullTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientNullTests : NullTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class NullTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class NullTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
......
...@@ -20,8 +20,10 @@ namespace Dapper.Tests ...@@ -20,8 +20,10 @@ namespace Dapper.Tests
{ {
[Collection(NonParallelDefinition.Name)] // because it creates SQL types that compete between the two providers [Collection(NonParallelDefinition.Name)] // because it creates SQL types that compete between the two providers
public sealed class SystemSqlClientParameterTests : ParameterTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientParameterTests : ParameterTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection(NonParallelDefinition.Name)] // because it creates SQL types that compete between the two providers [Collection(NonParallelDefinition.Name)] // because it creates SQL types that compete between the two providers
public sealed class MicrosoftSqlClientParameterTests : ParameterTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientParameterTests : ParameterTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class ParameterTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class ParameterTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
public class DbParams : SqlMapper.IDynamicParameters, IEnumerable<IDbDataParameter> public class DbParams : SqlMapper.IDynamicParameters, IEnumerable<IDbDataParameter>
......
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientProcedureTests : ProcedureTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientProcedureTests : ProcedureTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientProcedureTests : ProcedureTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientProcedureTests : ProcedureTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class ProcedureTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class ProcedureTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
namespace Dapper.Tests.Providers namespace Dapper.Tests.Providers
{ {
public sealed class SystemSqlClientEntityFrameworkTests : EntityFrameworkTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientEntityFrameworkTests : EntityFrameworkTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientEntityFrameworkTests : EntityFrameworkTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientEntityFrameworkTests : EntityFrameworkTests<MicrosoftSqlClientProvider> { }
#endif
[Collection("TypeHandlerTests")] [Collection("TypeHandlerTests")]
public abstract class EntityFrameworkTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class EntityFrameworkTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientLinq2SqlTests : Linq2SqlTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientLinq2SqlTests : Linq2SqlTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientLinq2SqlTests : Linq2SqlTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientLinq2SqlTests : Linq2SqlTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class Linq2SqlTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class Linq2SqlTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
using System; using System;
using System.Data;
using System.Data.Common; using System.Data.Common;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Xunit; using Xunit;
namespace Dapper.Tests namespace Dapper.Tests
...@@ -155,6 +157,52 @@ public void SO36303462_Tinyint_Bools() ...@@ -155,6 +157,52 @@ public void SO36303462_Tinyint_Bools()
} }
} }
[Fact]
public void Issue1277_ReaderSync()
{
using (var conn = Provider.GetMySqlConnection())
{
try { conn.Execute("drop table Issue1277_Test"); } catch { /* don't care */ }
conn.Execute("create table Issue1277_Test (Id int not null, IsBold tinyint not null);");
conn.Execute("insert Issue1277_Test (Id, IsBold) values (1,1);");
conn.Execute("insert Issue1277_Test (Id, IsBold) values (2,0);");
conn.Execute("insert Issue1277_Test (Id, IsBold) values (3,1);");
using (var reader = conn.ExecuteReader(
"select * from Issue1277_Test where Id < @id",
new { id = 42 }))
{
var table = new DataTable();
table.Load(reader);
Assert.Equal(2, table.Columns.Count);
Assert.Equal(3, table.Rows.Count);
}
}
}
[Fact]
public async Task Issue1277_ReaderAsync()
{
using (var conn = Provider.GetMySqlConnection())
{
try { await conn.ExecuteAsync("drop table Issue1277_Test"); } catch { /* don't care */ }
await conn.ExecuteAsync("create table Issue1277_Test (Id int not null, IsBold tinyint not null);");
await conn.ExecuteAsync("insert Issue1277_Test (Id, IsBold) values (1,1);");
await conn.ExecuteAsync("insert Issue1277_Test (Id, IsBold) values (2,0);");
await conn.ExecuteAsync("insert Issue1277_Test (Id, IsBold) values (3,1);");
using (var reader = await conn.ExecuteReaderAsync(
"select * from Issue1277_Test where Id < @id",
new { id = 42 }))
{
var table = new DataTable();
table.Load(reader);
Assert.Equal(2, table.Columns.Count);
Assert.Equal(3, table.Rows.Count);
}
}
}
private class SO36303462 private class SO36303462
{ {
public int Id { get; set; } public int Id { get; set; }
......
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientQueryMultipleTests : QueryMultipleTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientQueryMultipleTests : QueryMultipleTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientQueryMultipleTests : QueryMultipleTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientQueryMultipleTests : QueryMultipleTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class QueryMultipleTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class QueryMultipleTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
...@@ -72,10 +72,12 @@ public sealed class SystemSqlClientProvider : SqlServerDatabaseProvider ...@@ -72,10 +72,12 @@ public sealed class SystemSqlClientProvider : SqlServerDatabaseProvider
{ {
public override DbProviderFactory Factory => System.Data.SqlClient.SqlClientFactory.Instance; public override DbProviderFactory Factory => System.Data.SqlClient.SqlClientFactory.Instance;
} }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientProvider : SqlServerDatabaseProvider public sealed class MicrosoftSqlClientProvider : SqlServerDatabaseProvider
{ {
public override DbProviderFactory Factory => Microsoft.Data.SqlClient.SqlClientFactory.Instance; public override DbProviderFactory Factory => Microsoft.Data.SqlClient.SqlClientFactory.Instance;
} }
#endif
public abstract class TestBase<TProvider> : IDisposable where TProvider : DatabaseProvider public abstract class TestBase<TProvider> : IDisposable where TProvider : DatabaseProvider
{ {
......
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientTransactionTests : TransactionTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientTransactionTests : TransactionTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientTransactionTests : TransactionTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientTransactionTests : TransactionTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class TransactionTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class TransactionTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientTupleTests : TupleTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientTupleTests : TupleTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientTupleTests : TupleTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientTupleTests : TupleTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class TupleTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class TupleTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
...@@ -10,8 +10,10 @@ namespace Dapper.Tests ...@@ -10,8 +10,10 @@ namespace Dapper.Tests
{ {
[Collection(NonParallelDefinition.Name)] [Collection(NonParallelDefinition.Name)]
public sealed class SystemSqlClientTypeHandlerTests : TypeHandlerTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientTypeHandlerTests : TypeHandlerTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection(NonParallelDefinition.Name)] [Collection(NonParallelDefinition.Name)]
public sealed class MicrosoftSqlClientTypeHandlerTests : TypeHandlerTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientTypeHandlerTests : TypeHandlerTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class TypeHandlerTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class TypeHandlerTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
namespace Dapper.Tests namespace Dapper.Tests
{ {
public sealed class SystemSqlClientXmlTests : XmlTests<SystemSqlClientProvider> { } public sealed class SystemSqlClientXmlTests : XmlTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
public sealed class MicrosoftSqlClientXmlTests : XmlTests<MicrosoftSqlClientProvider> { } public sealed class MicrosoftSqlClientXmlTests : XmlTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class XmlTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider public abstract class XmlTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
{ {
[Fact] [Fact]
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<Title>Dapper</Title> <Title>Dapper</Title>
<Description>A high performance Micro-ORM supporting SQL Server, MySQL, Sqlite, SqlCE, Firebird etc..</Description> <Description>A high performance Micro-ORM supporting SQL Server, MySQL, Sqlite, SqlCE, Firebird etc..</Description>
<Authors>Sam Saffron;Marc Gravell;Nick Craver</Authors> <Authors>Sam Saffron;Marc Gravell;Nick Craver</Authors>
<TargetFrameworks>net451;netstandard1.3;netstandard2.0</TargetFrameworks> <TargetFrameworks>net451;netstandard1.3;netstandard2.0;netcoreapp2.1</TargetFrameworks>
</PropertyGroup> </PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net451'"> <ItemGroup Condition="'$(TargetFramework)' == 'net451'">
<Reference Include="System" /> <Reference Include="System" />
...@@ -19,6 +19,10 @@ ...@@ -19,6 +19,10 @@
<PackageReference Include="System.Reflection.TypeExtensions" Version="4.4.0" /> <PackageReference Include="System.Reflection.TypeExtensions" Version="4.4.0" />
<!-- it would be nice to use System.Data.Common here, but we need SqlClient for SqlDbType in 1.3, and legacy SqlDataRecord API--> <!-- it would be nice to use System.Data.Common here, but we need SqlClient for SqlDbType in 1.3, and legacy SqlDataRecord API-->
<!--<PackageReference Include="System.Data.Common" Version="4.3.0" />-->
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" /> <PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' "> <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
......
...@@ -84,7 +84,11 @@ static class StructuredHelper ...@@ -84,7 +84,11 @@ static class StructuredHelper
{ {
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, type); il.Emit(OpCodes.Castclass, type);
#if NETSTANDARD1_3
il.Emit(OpCodes.Ldc_I4, (int)30); // hard-code the known enum value
#else
il.Emit(OpCodes.Ldc_I4, (int)SqlDbType.Structured); il.Emit(OpCodes.Ldc_I4, (int)SqlDbType.Structured);
#endif
il.EmitCall(OpCodes.Callvirt, dbType.GetSetMethod(), null); il.EmitCall(OpCodes.Callvirt, dbType.GetSetMethod(), null);
} }
......
...@@ -1101,7 +1101,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn, ...@@ -1101,7 +1101,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
/// </code> /// </code>
/// </example> /// </example>
public static Task<IDataReader> ExecuteReaderAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => public static Task<IDataReader> ExecuteReaderAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) =>
ExecuteReaderImplAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered), CommandBehavior.Default); ExecuteWrappedReaderImplAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered), CommandBehavior.Default);
/// <summary> /// <summary>
/// Execute parameterized SQL and return an <see cref="IDataReader"/>. /// Execute parameterized SQL and return an <see cref="IDataReader"/>.
...@@ -1114,7 +1114,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn, ...@@ -1114,7 +1114,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
/// or <see cref="T:DataSet"/>. /// or <see cref="T:DataSet"/>.
/// </remarks> /// </remarks>
public static Task<IDataReader> ExecuteReaderAsync(this IDbConnection cnn, CommandDefinition command) => public static Task<IDataReader> ExecuteReaderAsync(this IDbConnection cnn, CommandDefinition command) =>
ExecuteReaderImplAsync(cnn, command, CommandBehavior.Default); ExecuteWrappedReaderImplAsync(cnn, command, CommandBehavior.Default);
/// <summary> /// <summary>
/// Execute parameterized SQL and return an <see cref="IDataReader"/>. /// Execute parameterized SQL and return an <see cref="IDataReader"/>.
...@@ -1128,26 +1128,27 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn, ...@@ -1128,26 +1128,27 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
/// or <see cref="T:DataSet"/>. /// or <see cref="T:DataSet"/>.
/// </remarks> /// </remarks>
public static Task<IDataReader> ExecuteReaderAsync(this IDbConnection cnn, CommandDefinition command, CommandBehavior commandBehavior) => public static Task<IDataReader> ExecuteReaderAsync(this IDbConnection cnn, CommandDefinition command, CommandBehavior commandBehavior) =>
ExecuteReaderImplAsync(cnn, command, commandBehavior); ExecuteWrappedReaderImplAsync(cnn, command, commandBehavior);
private static async Task<IDataReader> ExecuteReaderImplAsync(IDbConnection cnn, CommandDefinition command, CommandBehavior commandBehavior) private static async Task<IDataReader> ExecuteWrappedReaderImplAsync(IDbConnection cnn, CommandDefinition command, CommandBehavior commandBehavior)
{ {
Action<IDbCommand, object> paramReader = GetParameterReader(cnn, ref command); Action<IDbCommand, object> paramReader = GetParameterReader(cnn, ref command);
DbCommand cmd = null; DbCommand cmd = null;
bool wasClosed = cnn.State == ConnectionState.Closed; bool wasClosed = cnn.State == ConnectionState.Closed, disposeCommand = true;
try try
{ {
cmd = command.TrySetupAsyncCommand(cnn, paramReader); cmd = command.TrySetupAsyncCommand(cnn, paramReader);
if (wasClosed) await cnn.TryOpenAsync(command.CancellationToken).ConfigureAwait(false); if (wasClosed) await cnn.TryOpenAsync(command.CancellationToken).ConfigureAwait(false);
var reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, wasClosed, commandBehavior, command.CancellationToken).ConfigureAwait(false); var reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, wasClosed, commandBehavior, command.CancellationToken).ConfigureAwait(false);
wasClosed = false; wasClosed = false;
return reader; disposeCommand = false;
return WrappedReader.Create(cmd, reader);
} }
finally finally
{ {
if (wasClosed) cnn.Close(); if (wasClosed) cnn.Close();
cmd?.Dispose(); if (cmd != null && disposeCommand) cmd.Dispose();
} }
} }
......
...@@ -599,7 +599,7 @@ public static IDataReader ExecuteReader(this IDbConnection cnn, string sql, obje ...@@ -599,7 +599,7 @@ public static IDataReader ExecuteReader(this IDbConnection cnn, string sql, obje
{ {
var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered);
var reader = ExecuteReaderImpl(cnn, ref command, CommandBehavior.Default, out IDbCommand dbcmd); var reader = ExecuteReaderImpl(cnn, ref command, CommandBehavior.Default, out IDbCommand dbcmd);
return new WrappedReader(dbcmd, reader); return WrappedReader.Create(dbcmd, reader);
} }
/// <summary> /// <summary>
...@@ -615,7 +615,7 @@ public static IDataReader ExecuteReader(this IDbConnection cnn, string sql, obje ...@@ -615,7 +615,7 @@ public static IDataReader ExecuteReader(this IDbConnection cnn, string sql, obje
public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinition command) public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinition command)
{ {
var reader = ExecuteReaderImpl(cnn, ref command, CommandBehavior.Default, out IDbCommand dbcmd); var reader = ExecuteReaderImpl(cnn, ref command, CommandBehavior.Default, out IDbCommand dbcmd);
return new WrappedReader(dbcmd, reader); return WrappedReader.Create(dbcmd, reader);
} }
/// <summary> /// <summary>
...@@ -632,7 +632,7 @@ public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinitio ...@@ -632,7 +632,7 @@ public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinitio
public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinition command, CommandBehavior commandBehavior) public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinition command, CommandBehavior commandBehavior)
{ {
var reader = ExecuteReaderImpl(cnn, ref command, commandBehavior, out IDbCommand dbcmd); var reader = ExecuteReaderImpl(cnn, ref command, commandBehavior, out IDbCommand dbcmd);
return new WrappedReader(dbcmd, reader); return WrappedReader.Create(dbcmd, reader);
} }
/// <summary> /// <summary>
...@@ -3696,6 +3696,7 @@ public static void SetTypeName(this DataTable table, string typeName) ...@@ -3696,6 +3696,7 @@ public static void SetTypeName(this DataTable table, string typeName)
public static ICustomQueryParameter AsTableValuedParameter<T>(this IEnumerable<T> list, string typeName = null) where T : IDataRecord => public static ICustomQueryParameter AsTableValuedParameter<T>(this IEnumerable<T> list, string typeName = null) where T : IDataRecord =>
new SqlDataRecordListTVPParameter<T>(list, typeName); new SqlDataRecordListTVPParameter<T>(list, typeName);
/*
/// <summary> /// <summary>
/// Used to pass a IEnumerable&lt;SqlDataRecord&gt; as a TableValuedParameter. /// Used to pass a IEnumerable&lt;SqlDataRecord&gt; as a TableValuedParameter.
/// </summary> /// </summary>
...@@ -3704,6 +3705,7 @@ public static void SetTypeName(this DataTable table, string typeName) ...@@ -3704,6 +3705,7 @@ public static void SetTypeName(this DataTable table, string typeName)
public static ICustomQueryParameter AsTableValuedParameter(this IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord> list, string typeName = null) => public static ICustomQueryParameter AsTableValuedParameter(this IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord> list, string typeName = null) =>
new SqlDataRecordListTVPParameter<Microsoft.SqlServer.Server.SqlDataRecord>(list, typeName); new SqlDataRecordListTVPParameter<Microsoft.SqlServer.Server.SqlDataRecord>(list, typeName);
// ^^^ retained to avoid missing-method-exception; can presumably drop in a "major" // ^^^ retained to avoid missing-method-exception; can presumably drop in a "major"
*/
// one per thread // one per thread
[ThreadStatic] [ThreadStatic]
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment