未验证 提交 8152f2c7 编写于 作者: M Marc Gravell 提交者: GitHub

WIP: Lib updates and prepare for Microsoft.Data.SqlClient (#1313)

v2 work; primarily prep for split SqlClient
上级 6df95cbd
......@@ -5,8 +5,7 @@
<Title>Dapper.Contrib</Title>
<Description>The official collection of get, insert, update and delete helpers for Dapper.net. Also handles lists of entities and optional "dirty" tracking of interface-based entities.</Description>
<Authors>Sam Saffron;Johan Danforth</Authors>
<TargetFrameworks>net451;netstandard1.3;netstandard2.0</TargetFrameworks>
<!-- TODO: Docs -->
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
......@@ -15,16 +14,8 @@
<ItemGroup>
<ProjectReference Include="..\Dapper\Dapper.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net451'">
<Reference Include="System.Data" />
<Reference Include="System.Data.Linq" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' OR '$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -37,7 +37,7 @@ public static partial class SqlMapperExtensions
var dynParms = new DynamicParameters();
dynParms.Add("@id", id);
if (!type.IsInterface())
if (!type.IsInterface)
return (await connection.QueryAsync<T>(sql, dynParms, transaction, commandTimeout).ConfigureAwait(false)).FirstOrDefault();
var res = (await connection.QueryAsync<dynamic>(sql, dynParms).ConfigureAwait(false)).FirstOrDefault() as IDictionary<string, object>;
......@@ -51,7 +51,7 @@ public static partial class SqlMapperExtensions
{
var val = res[property.Name];
if (val == null) continue;
if (property.PropertyType.IsGenericType() && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var genericType = Nullable.GetUnderlyingType(property.PropertyType);
if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null);
......@@ -92,7 +92,7 @@ public static partial class SqlMapperExtensions
GetQueries[cacheType.TypeHandle] = sql;
}
if (!type.IsInterface())
if (!type.IsInterface)
{
return connection.QueryAsync<T>(sql, null, transaction, commandTimeout);
}
......@@ -110,7 +110,7 @@ public static partial class SqlMapperExtensions
{
var val = res[property.Name];
if (val == null) continue;
if (property.PropertyType.IsGenericType() && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var genericType = Nullable.GetUnderlyingType(property.PropertyType);
if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null);
......@@ -148,11 +148,11 @@ public static partial class SqlMapperExtensions
isList = true;
type = type.GetElementType();
}
else if (type.IsGenericType())
else if (type.IsGenericType)
{
var typeInfo = type.GetTypeInfo();
bool implementsGenericIEnumerableOrIsGenericIEnumerable =
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType() && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>);
if (implementsGenericIEnumerableOrIsGenericIEnumerable)
......@@ -219,11 +219,11 @@ public static partial class SqlMapperExtensions
{
type = type.GetElementType();
}
else if (type.IsGenericType())
else if (type.IsGenericType)
{
var typeInfo = type.GetTypeInfo();
bool implementsGenericIEnumerableOrIsGenericIEnumerable =
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType() && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>);
if (implementsGenericIEnumerableOrIsGenericIEnumerable)
......@@ -288,11 +288,11 @@ public static partial class SqlMapperExtensions
{
type = type.GetElementType();
}
else if (type.IsGenericType())
else if (type.IsGenericType)
{
var typeInfo = type.GetTypeInfo();
bool implementsGenericIEnumerableOrIsGenericIEnumerable =
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType() && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>);
if (implementsGenericIEnumerableOrIsGenericIEnumerable)
......
......@@ -190,7 +190,7 @@ private static PropertyInfo GetSingleKey<T>(string method)
T obj;
if (type.IsInterface())
if (type.IsInterface)
{
var res = connection.Query(sql, dynParms).FirstOrDefault() as IDictionary<string, object>;
......@@ -203,7 +203,7 @@ private static PropertyInfo GetSingleKey<T>(string method)
{
var val = res[property.Name];
if (val == null) continue;
if (property.PropertyType.IsGenericType() && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var genericType = Nullable.GetUnderlyingType(property.PropertyType);
if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null);
......@@ -248,7 +248,7 @@ private static PropertyInfo GetSingleKey<T>(string method)
GetQueries[cacheType.TypeHandle] = sql;
}
if (!type.IsInterface()) return connection.Query<T>(sql, null, transaction, commandTimeout: commandTimeout);
if (!type.IsInterface) return connection.Query<T>(sql, null, transaction, commandTimeout: commandTimeout);
var result = connection.Query(sql);
var list = new List<T>();
......@@ -259,7 +259,7 @@ private static PropertyInfo GetSingleKey<T>(string method)
{
var val = res[property.Name];
if (val == null) continue;
if (property.PropertyType.IsGenericType() && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
var genericType = Nullable.GetUnderlyingType(property.PropertyType);
if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null);
......@@ -307,7 +307,7 @@ private static string GetTableName(Type type)
else
{
name = type.Name + "s";
if (type.IsInterface() && name.StartsWith("I"))
if (type.IsInterface && name.StartsWith("I"))
name = name.Substring(1);
}
}
......@@ -336,11 +336,11 @@ private static string GetTableName(Type type)
isList = true;
type = type.GetElementType();
}
else if (type.IsGenericType())
else if (type.IsGenericType)
{
var typeInfo = type.GetTypeInfo();
bool implementsGenericIEnumerableOrIsGenericIEnumerable =
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType() && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>);
if (implementsGenericIEnumerableOrIsGenericIEnumerable)
......@@ -417,11 +417,11 @@ private static string GetTableName(Type type)
{
type = type.GetElementType();
}
else if (type.IsGenericType())
else if (type.IsGenericType)
{
var typeInfo = type.GetTypeInfo();
bool implementsGenericIEnumerableOrIsGenericIEnumerable =
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType() && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>);
if (implementsGenericIEnumerableOrIsGenericIEnumerable)
......@@ -486,11 +486,11 @@ private static string GetTableName(Type type)
{
type = type.GetElementType();
}
else if (type.IsGenericType())
else if (type.IsGenericType)
{
var typeInfo = type.GetTypeInfo();
bool implementsGenericIEnumerableOrIsGenericIEnumerable =
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType() && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>);
if (implementsGenericIEnumerableOrIsGenericIEnumerable)
......
......@@ -4,7 +4,7 @@
<Title>Dapper: Entity Framework type handlers (with a strong name)</Title>
<Description>Extension handlers for entity framework</Description>
<Authors>Marc Gravell;Nick Craver</Authors>
<TargetFrameworks>net451</TargetFrameworks>
<TargetFrameworks>net462</TargetFrameworks>
<AssemblyOriginatorKeyFile>../Dapper.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
......@@ -16,13 +16,8 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Dapper.StrongName\Dapper.StrongName.csproj" />
<!-- note: 6.2.0 has regressions; don't force the update -->
<PackageReference Include="EntityFramework" Version="6.1.3" />
<PackageReference Include="Microsoft.SqlServer.Types" Version="11.0.2" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.Linq" />
<Reference Include="System.Xml" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
<PackageReference Include="Microsoft.SqlServer.Types" Version="14.0.1016.290" />
</ItemGroup>
</Project>
......@@ -5,18 +5,13 @@
<AssemblyTitle>Dapper entity framework type handlers</AssemblyTitle>
<VersionPrefix>1.50.2</VersionPrefix>
<Authors>Marc Gravell;Nick Craver</Authors>
<TargetFrameworks>net451</TargetFrameworks>
<TargetFrameworks>net462</TargetFrameworks>
<PackageTags>orm;sql;micro-orm</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Dapper\Dapper.csproj" />
<!-- note: 6.2.0 has regressions; don't force the update -->
<PackageReference Include="EntityFramework" Version="6.1.3" />
<PackageReference Include="Microsoft.SqlServer.Types" Version="11.0.2" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.Linq" />
<Reference Include="System.Xml" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
<PackageReference Include="Microsoft.SqlServer.Types" Version="14.0.1016.290" />
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -6,7 +6,7 @@
<Description>Trivial micro-orm implemented on Dapper, provides with CRUD helpers.</Description>
<Authors>Sam Saffron</Authors>
<Copyright>2017 Sam Saffron</Copyright>
<TargetFrameworks>net451;netstandard1.3</TargetFrameworks>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<!-- TODO: Docs -->
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
......@@ -16,14 +16,8 @@
<ItemGroup>
<ProjectReference Include="..\Dapper\Dapper.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net451'">
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.Linq" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -257,7 +257,7 @@ protected Action<TDatabase> CreateTableConstructor(params Type[] tableTypes)
var il = dm.GetILGenerator();
var setters = GetType().GetProperties()
.Where(p => p.PropertyType.IsGenericType() && tableTypes.Contains(p.PropertyType.GetGenericTypeDefinition()))
.Where(p => p.PropertyType.IsGenericType && tableTypes.Contains(p.PropertyType.GetGenericTypeDefinition()))
.Select(p => Tuple.Create(
p.GetSetMethod(true),
p.PropertyType.GetConstructor(new[] { typeof(TDatabase), typeof(string) }),
......
......@@ -91,8 +91,8 @@ private static List<PropertyInfo> RelevantProperties()
p.GetSetMethod(true) != null
&& p.GetGetMethod(true) != null
&& (p.PropertyType == typeof(string)
|| p.PropertyType.IsValueType()
|| (p.PropertyType.IsGenericType() && p.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)))
|| p.PropertyType.IsValueType
|| (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)))
).ToList();
}
......@@ -109,13 +109,13 @@ private static bool AreEqual<U>(U first, U second)
var il = dm.GetILGenerator();
// change list
il.DeclareLocal(typeof(List<Change>));
il.DeclareLocal(typeof(Change));
il.DeclareLocal(typeof(object)); // boxed change
var list = il.DeclareLocal(typeof(List<Change>));
var change = il.DeclareLocal(typeof(Change));
var boxed = il.DeclareLocal(typeof(object)); // boxed change
il.Emit(OpCodes.Newobj, typeof(List<Change>).GetConstructor(Type.EmptyTypes));
// [list]
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Stloc, list);
foreach (var prop in RelevantProperties())
{
......@@ -138,7 +138,7 @@ private static bool AreEqual<U>(U first, U second)
// [original prop val, current prop val, current prop val boxed]
}
il.Emit(OpCodes.Stloc_2);
il.Emit(OpCodes.Stloc, boxed);
// [original prop val, current prop val]
il.EmitCall(OpCodes.Call, typeof(Snapshot<T>).GetMethod(nameof(AreEqual), BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(new Type[] { prop.PropertyType }), null);
......@@ -153,7 +153,7 @@ private static bool AreEqual<U>(U first, U second)
il.Emit(OpCodes.Dup);
// [change,change]
il.Emit(OpCodes.Stloc_1);
il.Emit(OpCodes.Stloc, change);
// [change]
il.Emit(OpCodes.Ldstr, prop.Name);
......@@ -161,18 +161,18 @@ private static bool AreEqual<U>(U first, U second)
il.Emit(OpCodes.Callvirt, typeof(Change).GetMethod("set_Name"));
// []
il.Emit(OpCodes.Ldloc_1);
il.Emit(OpCodes.Ldloc, change);
// [change]
il.Emit(OpCodes.Ldloc_2);
il.Emit(OpCodes.Ldloc, boxed);
// [change, boxed]
il.Emit(OpCodes.Callvirt, typeof(Change).GetMethod("set_NewValue"));
// []
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldloc, list);
// [change list]
il.Emit(OpCodes.Ldloc_1);
il.Emit(OpCodes.Ldloc, change);
// [change list, change]
il.Emit(OpCodes.Callvirt, typeof(List<Change>).GetMethod("Add"));
// []
......@@ -180,7 +180,7 @@ private static bool AreEqual<U>(U first, U second)
il.MarkLabel(skip);
}
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldloc, list);
// [change list]
il.Emit(OpCodes.Ret);
......@@ -195,14 +195,14 @@ private static bool AreEqual<U>(U first, U second)
var il = dm.GetILGenerator();
il.DeclareLocal(typeof(T));
var typed = il.DeclareLocal(typeof(T));
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Stloc, typed);
foreach (var prop in RelevantProperties())
{
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldloc, typed);
// [clone]
il.Emit(OpCodes.Ldarg_0);
// [clone, source]
......@@ -213,7 +213,7 @@ private static bool AreEqual<U>(U first, U second)
}
// Load new constructed obj on eval stack -> 1 item on stack
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldloc, typed);
// Return constructed object. --> 0 items on stack
il.Emit(OpCodes.Ret);
......
......@@ -5,21 +5,15 @@
<Title>Dapper SqlBuilder component</Title>
<Description>The Dapper SqlBuilder component, for building SQL queries dynamically.</Description>
<Authors>Sam Saffron, Johan Danforth</Authors>
<TargetFrameworks>net451;netstandard1.3</TargetFrameworks>
<!-- TODO: Docs -->
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Dapper\Dapper.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net451'">
<Reference Include="System.Data" />
<Reference Include="System.Data.Linq" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -5,37 +5,15 @@
<Title>Dapper (Strong Named)</Title>
<Description>A high performance Micro-ORM supporting SQL Server, MySQL, Sqlite, SqlCE, Firebird etc..</Description>
<Authors>Sam Saffron;Marc Gravell;Nick Craver</Authors>
<TargetFrameworks>net451;netstandard1.3;netstandard2.0;netcoreapp2.1</TargetFrameworks>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Dapper\**\*.cs" Exclude="..\Dapper\obj\**\*.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net451'">
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' OR '$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.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-->
<!--<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" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<PackageReference Include="System.Collections.Concurrent" Version="4.3.0" />
<PackageReference Include="System.Collections.NonGeneric" Version="4.3.0" />
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
<PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
</ItemGroup>
</Project>
......@@ -6,7 +6,7 @@
<DebugType>portable</DebugType>
<OutputType>Exe</OutputType>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<TargetFrameworks>netcoreapp1.0;netcoreapp2.0</TargetFrameworks>
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Dapper.Tests\Helpers\XunitSkippable.cs;..\Dapper\TypeExtensions.cs" />
......@@ -16,11 +16,15 @@
<ProjectReference Include="..\Dapper\Dapper.csproj" />
<ProjectReference Include="..\Dapper.Contrib\Dapper.Contrib.csproj" />
<ProjectReference Include="..\Dapper.SqlBuilder\Dapper.SqlBuilder.csproj" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="1.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="MySqlConnector" Version="0.44.1" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.6" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="MySqlConnector" Version="0.56.0" />
<PackageReference Include="xunit" Version="$(xUnitVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitVersion)" />
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Data.SqlClient" Version="4.6.1" />
</ItemGroup>
<!-- note: define SQLCE if SQL CE is available -->
</Project>
......@@ -2,14 +2,10 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Transactions;
using Dapper.Contrib.Extensions;
using Xunit;
#if !NETCOREAPP1_0 && !NETCOREAPP2_0
using System.Transactions;
using System.Data.SqlServerCe;
#endif
using FactAttribute = Dapper.Tests.Contrib.SkippableFactAttribute;
namespace Dapper.Tests.Contrib
......@@ -525,7 +521,7 @@ public void InsertGetUpdate()
}
}
#if !NETCOREAPP1_0 && !NETCOREAPP2_0
#if SQLCE
[Fact(Skip = "Not parallel friendly - thinking about how to test this")]
public void InsertWithCustomDbType()
{
......@@ -563,7 +559,7 @@ public void InsertWithCustomTableNameMapper()
{
SqlMapperExtensions.TableNameMapper = type =>
{
switch (type.Name())
switch (type.Name)
{
case "Person":
return "People";
......@@ -573,7 +569,7 @@ public void InsertWithCustomTableNameMapper()
return tableattr.Name;
var name = type.Name + "s";
if (type.IsInterface() && name.StartsWith("I"))
if (type.IsInterface && name.StartsWith("I"))
return name.Substring(1);
return name;
}
......@@ -652,8 +648,7 @@ public void Transactions()
Assert.Equal(car.Name, orgName);
}
}
#if !NETCOREAPP1_0 && !NETCOREAPP2_0
#if TRANSCOPE
[Fact]
public void TransactionScope()
{
......@@ -665,7 +660,7 @@ public void TransactionScope()
txscope.Dispose(); //rollback
Assert.IsNull(connection.Get<Car>(id)); //returns null - car with that id should not exist
Assert.Null(connection.Get<Car>(id)); //returns null - car with that id should not exist
}
}
}
......
......@@ -7,10 +7,6 @@
using Xunit;
using Xunit.Sdk;
#if !NETCOREAPP1_0 && !NETCOREAPP2_0
using System.Data.SqlServerCe;
#endif
namespace Dapper.Tests.Contrib
{
// The test suites here implement TestSuiteBase so that each provider runs
......@@ -72,7 +68,7 @@ public class MySqlServerTestSuite : TestSuite
public override IDbConnection GetConnection()
{
if (_skip) throw new SkipTestException("Skipping MySQL Tests - no server.");
if (_skip) Skip.Inconclusive("Skipping MySQL Tests - no server.");
return new MySqlConnection(ConnectionString);
}
......@@ -148,7 +144,8 @@ static SQLiteTestSuite()
}
}
#if !NETCOREAPP1_0 && !NETCOREAPP2_0
#if SQLCE
public class SqlCETestSuite : TestSuite
{
const string FileName = "Test.DB.sdf";
......
......@@ -22,7 +22,7 @@ public Config()
Add(MarkdownExporter.GitHub);
Add(HtmlExporter.Default);
var md = new MemoryDiagnoser();
var md = MemoryDiagnoser.Default;
Add(md);
Add(new ORMColum());
Add(TargetMethodColumn.Method);
......@@ -30,8 +30,8 @@ public Config()
Add(StatisticColumn.Mean);
//Add(StatisticColumn.StdDev);
//Add(StatisticColumn.Error);
Add(BaselineScaledColumn.Scaled);
Add(md.GetColumnProvider());
Add(BaselineRatioColumn.RatioMean);
//Add(md.GetColumnProvider());
Add(Job.ShortRun
.WithLaunchCount(1)
......@@ -39,8 +39,8 @@ public Config()
.WithUnrollFactor(Iterations)
.WithIterationCount(1)
);
Set(new DefaultOrderer(SummaryOrderPolicy.FastestToSlowest));
SummaryPerType = false;
Orderer = new DefaultOrderer(SummaryOrderPolicy.FastestToSlowest);
Options |= ConfigOptions.JoinSummary;
}
}
}
......@@ -12,27 +12,27 @@
<ProjectReference Include="..\Dapper\Dapper.csproj" />
<ProjectReference Include="..\Dapper.Contrib\Dapper.Contrib.csproj" />
<ProjectReference Include="..\Dapper.EntityFramework\Dapper.EntityFramework.csproj" />
<PackageReference Include="Dashing" Version="2.0.7" />
<PackageReference Include="Dashing.Weaver" Version="2.0.7" />
<PackageReference Include="Dashing" Version="2.2.0" />
<PackageReference Include="Dashing.Weaver" Version="2.2.0" />
<PackageReference Include="Belgrade.Sql.Client" Version="1.1.4" />
<PackageReference Include="BenchmarkDotNet" Version="0.11.1" />
<PackageReference Include="DevExpress.Xpo" Version="18.1.6" />
<PackageReference Include="BenchmarkDotNet" Version="0.11.5" />
<PackageReference Include="DevExpress.Xpo" Version="19.1.5" />
<!--<PackageReference Include="BLToolkit" Version="4.3.6" />-->
<PackageReference Include="EntityFramework" Version="6.2.0" />
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="6.3.0" />
<PackageReference Include="linq2db.SqlServer" Version="2.3.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.2" />
<PackageReference Include="Microsoft.SqlServer.Types" Version="14.0.314.76" />
<PackageReference Include="MySqlConnector" Version="0.44.1" />
<PackageReference Include="NHibernate" Version="5.1.3" />
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="7.0.0" />
<PackageReference Include="linq2db.SqlServer" Version="2.9.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.6" />
<PackageReference Include="Microsoft.SqlServer.Types" Version="14.0.1016.290" />
<PackageReference Include="MySqlConnector" Version="0.56.0" />
<PackageReference Include="NHibernate" Version="5.2.5" />
<PackageReference Include="Iesi.Collections" Version="4.0.4" />
<PackageReference Include="Npgsql" Version="4.0.3" />
<PackageReference Include="Npgsql" Version="4.0.9" />
<PackageReference Include="PetaPoco" Version="5.1.306" />
<PackageReference Include="ServiceStack.OrmLite.SqlServer.Signed" Version="4.5.14" />
<PackageReference Include="Soma" Version="1.9.0.1" />
<PackageReference Include="SubSonic" Version="3.0.0.4" />
<PackageReference Include="Susanoo.SqlServer" Version="1.2.4.2" />
<PackageReference Include="System.Data.SQLite" Version="1.0.109.1" />
<PackageReference Include="System.Data.SQLite" Version="1.0.111" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.Linq" />
......
......@@ -19,7 +19,7 @@ public string GetValue(Summary summary, BenchmarkCase benchmarkCase)
return type.GetCustomAttribute<DescriptionAttribute>()?.Description ?? type.Name.Replace("Benchmarks", string.Empty);
}
public string GetValue(Summary summary, BenchmarkCase benchmarkCase, ISummaryStyle style) => GetValue(summary, benchmarkCase);
public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);
public bool IsAvailable(Summary summary) => true;
public bool AlwaysShow => true;
......
......@@ -17,7 +17,7 @@ public string GetValue(Summary summary, BenchmarkCase benchmarkCase)
return type == typeof(object) ? "dynamic" : type.Name;
}
public string GetValue(Summary summary, BenchmarkCase benchmarkCase, ISummaryStyle style) => GetValue(summary, benchmarkCase);
public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);
public bool IsAvailable(Summary summary) => true;
public bool AlwaysShow => true;
......
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" culture="neutral" />
<bindingRedirect oldVersion="10.0.0.0" newVersion="14.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
......@@ -6,6 +6,7 @@
using System.Threading;
using Xunit;
using System.Data.Common;
using Xunit.Abstractions;
namespace Dapper.Tests
{
......@@ -17,10 +18,14 @@ public sealed class MicrosoftSqlClientAsyncTests : AsyncTests<MicrosoftSqlClient
#endif
[Collection(NonParallelDefinition.Name)]
public sealed class SystemSqlClientAsyncQueryCacheTests : AsyncQueryCacheTests<SystemSqlClientProvider> { }
public sealed class SystemSqlClientAsyncQueryCacheTests : AsyncQueryCacheTests<SystemSqlClientProvider> {
public SystemSqlClientAsyncQueryCacheTests(ITestOutputHelper log) : base(log) { }
}
#if MSSQLCLIENT
[Collection(NonParallelDefinition.Name)]
public sealed class MicrosoftSqlClientAsyncQueryCacheTests : AsyncQueryCacheTests<MicrosoftSqlClientProvider> { }
public sealed class MicrosoftSqlClientAsyncQueryCacheTests : AsyncQueryCacheTests<MicrosoftSqlClientProvider> {
public MicrosoftSqlClientAsyncQueryCacheTests(ITestOutputHelper log) : base(log) { }
}
#endif
......@@ -818,6 +823,8 @@ public async Task Issue563_QueryAsyncShouldThrowException()
[Collection(NonParallelDefinition.Name)]
public abstract class AsyncQueryCacheTests<TProvider> : TestBase<TProvider> where TProvider : SqlServerDatabaseProvider
{
private readonly ITestOutputHelper _log;
public AsyncQueryCacheTests(ITestOutputHelper log) => _log = log;
private DbConnection _marsConnection;
private DbConnection MarsConnection => _marsConnection ?? (_marsConnection = Provider.GetOpenConnection(true));
......@@ -847,8 +854,10 @@ public void AssertNoCacheWorksForQueryMultiple()
d = multi.Read<int>().Single();
}
int after = SqlMapper.GetCachedSQLCount();
Assert.Equal(0, before);
Assert.Equal(0, after);
_log?.WriteLine($"before: {before}; after: {after}");
// too brittle in concurrent tests to assert
// Assert.Equal(0, before);
// Assert.Equal(0, after);
Assert.Equal(123, c);
Assert.Equal(456, d);
}
......
......@@ -5,8 +5,10 @@
namespace Dapper.Tests
{
[Collection("ConstructorTests")]
public sealed class SystemSqlClientConstructorTests : ConstructorTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("ConstructorTests")]
public sealed class MicrosoftSqlClientConstructorTests : ConstructorTests<MicrosoftSqlClientProvider> { }
#endif
......
......@@ -6,41 +6,60 @@
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<TargetFrameworks>netcoreapp2.1;net46;netcoreapp2.0;net472</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1;net462;net472</TargetFrameworks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net46' OR '$(TargetFramework)' == 'net472'">
<PropertyGroup Condition="'$(TargetFramework)' == 'net462' OR '$(TargetFramework)' == 'net472'">
<DefineConstants>$(DefineConstants);ENTITY_FRAMEWORK;LINQ2SQL;OLEDB</DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Remove="Test.DB.sdf" />
</ItemGroup>
<!-- these two go together
<PropertyGroup>
<DefineConstants>$(DefineConstants);MSSQLCLIENT</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Data.SqlClient" Version="1.0.19128.1-Preview" />
<PackageReference Include="System.Data.SqlClient" Version="4.6.1" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="1.0.19221.1-Preview" />
<PackageReference Include="Microsoft.SqlServer.Types" Version="14.0.1016.290"
Condition="'$(TargetFramework)' == 'net462' OR '$(TargetFramework)' == 'net472'"/>
</ItemGroup>
<ItemGroup Condition="'$(Platform)'=='x64'">
<Content Include="$(USERPROFILE)\.nuget\packages\microsoft.sqlserver.types\14.0.1016.290\nativeBinaries\x64\*.dll"
Condition="'$(TargetFramework)' == 'net462' OR '$(TargetFramework)' == 'net472'">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup Condition="'$(Platform)'=='x86'">
<Content Include="$(USERPROFILE)\.nuget\packages\microsoft.sqlserver.types\14.0.1016.290\nativeBinaries\x86\*.dll"
Condition="'$(TargetFramework)' == 'net462' OR '$(TargetFramework)' == 'net472'">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\Dapper\Dapper.csproj" />
<ProjectReference Include="..\Dapper.Contrib\Dapper.Contrib.csproj" />
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="5.9.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="MySqlConnector" Version="0.44.1" />
<PackageReference Include="Npgsql" Version="3.2.5" />
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="7.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="MySqlConnector" Version="0.56.0" />
<PackageReference Include="Npgsql" Version="4.0.9" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="xunit" Version="$(xUnitVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitVersion)" />
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(xUnitVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net46' OR '$(TargetFramework)' == 'net472'">
<ItemGroup Condition="'$(TargetFramework)' == 'net462' OR '$(TargetFramework)' == 'net472'">
<ProjectReference Include="..\Dapper.EntityFramework\Dapper.EntityFramework.csproj" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="1.1.1" />
<PackageReference Include="Microsoft.SqlServer.Types" Version="14.0.314.76" />
<PackageReference Include="Microsoft.SqlServer.Types" Version="14.0.1016.290" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.Linq" />
......@@ -50,23 +69,10 @@
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp1.0'">
<PackageReference Include="Microsoft.Data.Sqlite" Version="1.1.1" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.0.0" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.6" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.6" />
</ItemGroup>
<PropertyGroup>
<PostBuildEvent>
if not exist "$(TargetDir)x86" md "$(TargetDir)x86"
xcopy /s /y /q "$(NuGetPackageRoot)\Microsoft.SqlServer.Types\14.0.314.76\NativeBinaries\x86\*.*" "$(TargetDir)x86"
if not exist "$(TargetDir)x64" md "$(TargetDir)x64"
xcopy /s /y /q "$(NuGetPackageRoot)\Microsoft.SqlServer.Types\14.0.314.76\NativeBinaries\x64\*.*" "$(TargetDir)x64"
</PostBuildEvent>
</PropertyGroup>
</Project>
......@@ -4,8 +4,10 @@
namespace Dapper.Tests
{
[Collection("DataReaderTests")]
public sealed class SystemSqlClientDataReaderTests : DataReaderTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("DataReaderTests")]
public sealed class MicrosoftSqlClientDataReaderTests : DataReaderTests<MicrosoftSqlClientProvider> { }
#endif
......
......@@ -5,8 +5,10 @@
namespace Dapper.Tests
{
[Collection("DecimalTests")]
public sealed class SystemSqlClientDecimalTests : DecimalTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("DecimalTests")]
public sealed class MicrosoftSqlClientDecimalTests : DecimalTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class DecimalTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
......@@ -4,8 +4,10 @@
namespace Dapper.Tests
{
[Collection("EnumTests")]
public sealed class SystemSqlClientEnumTests : EnumTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("EnumTests")]
public sealed class MicrosoftSqlClientEnumTests : EnumTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class EnumTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
using System;
using Xunit;
using Xunit.Sdk;
namespace Dapper.Tests
{
/// <summary>
/// <para>Override for <see cref="Xunit.FactAttribute"/> that truncates our DisplayName down.</para>
/// <para>
/// Attribute that is applied to a method to indicate that it is a fact that should
/// be run by the test runner. It can also be extended to support a customized definition
/// of a test method.
/// </para>
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("Dapper.Tests.FactDiscoverer", "Dapper.Tests")]
public class FactAttribute : Xunit.FactAttribute
{
}
/// <summary>
/// <para>Override for <see cref="Xunit.TheoryAttribute"/> that truncates our DisplayName down.</para>
/// <para>
/// Marks a test method as being a data theory. Data theories are tests which are
/// fed various bits of data from a data source, mapping to parameters on the test
/// method. If the data source contains multiple rows, then the test method is executed
/// multiple times (once with each data row). Data is provided by attributes which
/// derive from Xunit.Sdk.DataAttribute (notably, Xunit.InlineDataAttribute and Xunit.MemberDataAttribute).
/// </para>
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("Dapper.Tests.TheoryDiscoverer", "Dapper.Tests")]
public class TheoryAttribute : Xunit.TheoryAttribute { }
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class FactLongRunningAttribute : FactAttribute
{
......
......@@ -9,6 +9,17 @@
namespace Dapper.Tests
{
public static class Skip
{
public static void Inconclusive(string reason = "inconclusive")
=> throw new SkipTestException(reason);
public static void If<T>(object obj, string reason = null)
where T : class
{
if (obj is T) Skip.Inconclusive(reason ?? $"not valid for {typeof(T).FullName}");
}
}
public class SkipTestException : Exception
{
public SkipTestException(string reason) : base(reason)
......@@ -16,31 +27,40 @@ public SkipTestException(string reason) : base(reason)
}
}
// Most of the below is a direct copy & port from the wonderful examples by Brad Wilson at
// https://github.com/xunit/samples.xunit/tree/master/DynamicSkipExample
public class SkippableFactDiscoverer : IXunitTestCaseDiscoverer
public class FactDiscoverer : Xunit.Sdk.FactDiscoverer
{
private readonly IMessageSink _diagnosticMessageSink;
public FactDiscoverer(IMessageSink diagnosticMessageSink) : base(diagnosticMessageSink) { }
public SkippableFactDiscoverer(IMessageSink diagnosticMessageSink)
{
_diagnosticMessageSink = diagnosticMessageSink;
}
protected override IXunitTestCase CreateTestCase(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
=> new SkippableTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod);
}
public IEnumerable<IXunitTestCase> Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
{
yield return new SkippableFactTestCase(_diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod);
}
public class TheoryDiscoverer : Xunit.Sdk.TheoryDiscoverer
{
public TheoryDiscoverer(IMessageSink diagnosticMessageSink) : base(diagnosticMessageSink) { }
protected override IEnumerable<IXunitTestCase> CreateTestCasesForDataRow(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute, object[] dataRow)
=> new[] { new SkippableTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, dataRow) };
protected override IEnumerable<IXunitTestCase> CreateTestCasesForSkip(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute, string skipReason)
=> new[] { new SkippableTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod) };
protected override IEnumerable<IXunitTestCase> CreateTestCasesForTheory(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute)
=> new[] { new SkippableTheoryTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod) };
protected override IEnumerable<IXunitTestCase> CreateTestCasesForSkippedDataRow(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo theoryAttribute, object[] dataRow, string skipReason)
=> new[] { new NamedSkippedDataRowTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), discoveryOptions.MethodDisplayOptionsOrDefault(), testMethod, skipReason, dataRow) };
}
public class SkippableFactTestCase : XunitTestCase
public class SkippableTestCase : XunitTestCase
{
protected override string GetDisplayName(IAttributeInfo factAttribute, string displayName) =>
base.GetDisplayName(factAttribute, displayName).StripName();
[Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
public SkippableFactTestCase()
{
}
public SkippableTestCase() { }
public SkippableFactTestCase(IMessageSink diagnosticMessageSink, TestMethodDisplay defaultMethodDisplay, TestMethodDisplayOptions defaultMethodDisplayOptions, ITestMethod testMethod, object[] testMethodArguments = null)
public SkippableTestCase(IMessageSink diagnosticMessageSink, TestMethodDisplay defaultMethodDisplay, TestMethodDisplayOptions defaultMethodDisplayOptions, ITestMethod testMethod, object[] testMethodArguments = null)
: base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod, testMethodArguments)
{
}
......@@ -52,36 +72,56 @@ public SkippableFactTestCase(IMessageSink diagnosticMessageSink, TestMethodDispl
ExceptionAggregator aggregator,
CancellationTokenSource cancellationTokenSource)
{
var skipMessageBus = new SkippableFactMessageBus(messageBus);
var result = await base.RunAsync(
diagnosticMessageSink,
skipMessageBus,
constructorArguments,
aggregator,
cancellationTokenSource).ConfigureAwait(false);
if (skipMessageBus.DynamicallySkippedTestCount > 0)
{
result.Failed -= skipMessageBus.DynamicallySkippedTestCount;
result.Skipped += skipMessageBus.DynamicallySkippedTestCount;
}
return result;
var skipMessageBus = new SkippableMessageBus(messageBus);
var result = await base.RunAsync(diagnosticMessageSink, skipMessageBus, constructorArguments, aggregator, cancellationTokenSource).ConfigureAwait(false);
return result.Update(skipMessageBus);
}
}
public class SkippableFactMessageBus : IMessageBus
public class SkippableTheoryTestCase : XunitTheoryTestCase
{
private readonly IMessageBus _innerBus;
public SkippableFactMessageBus(IMessageBus innerBus)
protected override string GetDisplayName(IAttributeInfo factAttribute, string displayName) =>
base.GetDisplayName(factAttribute, displayName).StripName();
[Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
public SkippableTheoryTestCase() { }
public SkippableTheoryTestCase(IMessageSink diagnosticMessageSink, TestMethodDisplay defaultMethodDisplay, TestMethodDisplayOptions defaultMethodDisplayOptions, ITestMethod testMethod)
: base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod) { }
public override async Task<RunSummary> RunAsync(
IMessageSink diagnosticMessageSink,
IMessageBus messageBus,
object[] constructorArguments,
ExceptionAggregator aggregator,
CancellationTokenSource cancellationTokenSource)
{
_innerBus = innerBus;
var skipMessageBus = new SkippableMessageBus(messageBus);
var result = await base.RunAsync(diagnosticMessageSink, skipMessageBus, constructorArguments, aggregator, cancellationTokenSource).ConfigureAwait(false);
return result.Update(skipMessageBus);
}
}
public class NamedSkippedDataRowTestCase : XunitSkippedDataRowTestCase
{
protected override string GetDisplayName(IAttributeInfo factAttribute, string displayName) =>
base.GetDisplayName(factAttribute, displayName).StripName();
[Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")]
public NamedSkippedDataRowTestCase() { }
public NamedSkippedDataRowTestCase(IMessageSink diagnosticMessageSink, TestMethodDisplay defaultMethodDisplay, TestMethodDisplayOptions defaultMethodDisplayOptions, ITestMethod testMethod, string skipReason, object[] testMethodArguments = null)
: base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod, skipReason, testMethodArguments) { }
}
public class SkippableMessageBus : IMessageBus
{
private readonly IMessageBus InnerBus;
public SkippableMessageBus(IMessageBus innerBus) => InnerBus = innerBus;
public int DynamicallySkippedTestCount { get; private set; }
public void Dispose()
{
}
public void Dispose() { }
public bool QueueMessage(IMessageSinkMessage message)
{
......@@ -91,10 +131,26 @@ public bool QueueMessage(IMessageSinkMessage message)
if (exceptionType == typeof(SkipTestException).FullName)
{
DynamicallySkippedTestCount++;
return _innerBus.QueueMessage(new TestSkipped(testFailed.Test, testFailed.Messages.FirstOrDefault()));
return InnerBus.QueueMessage(new TestSkipped(testFailed.Test, testFailed.Messages.FirstOrDefault()));
}
}
return _innerBus.QueueMessage(message);
return InnerBus.QueueMessage(message);
}
}
internal static class XUnitExtensions
{
internal static string StripName(this string name) =>
name.Replace("Dapper.Tests.", "");
public static RunSummary Update(this RunSummary summary, SkippableMessageBus bus)
{
if (bus.DynamicallySkippedTestCount > 0)
{
summary.Failed -= bus.DynamicallySkippedTestCount;
summary.Skipped += bus.DynamicallySkippedTestCount;
}
return summary;
}
}
}
......@@ -3,8 +3,10 @@
namespace Dapper.Tests
{
[Collection("LiteralTests")]
public sealed class SystemSqlClientLiteralTests : LiteralTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("LiteralTests")]
public sealed class MicrosoftSqlClientLiteralTests : LiteralTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class LiteralTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
......@@ -39,8 +39,10 @@ public GenericUriParser(GenericUriParserOptions options)
namespace Dapper.Tests
{
[Collection("MiscTests")]
public sealed class SystemSqlClientMiscTests : MiscTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("MiscTests")]
public sealed class MicrosoftSqlClientMiscTests : MiscTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class MiscTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
......@@ -6,8 +6,10 @@
namespace Dapper.Tests
{
[Collection("MultiMapTests")]
public sealed class SystemSqlClientMultiMapTests : MultiMapTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("MultiMapTests")]
public sealed class MicrosoftSqlClientMultiMapTests : MultiMapTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class MultiMapTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
......@@ -43,7 +43,19 @@ void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command, SqlMapper.Id
}
}
private static List<Microsoft.SqlServer.Server.SqlDataRecord> CreateSqlDataRecordList(IEnumerable<int> numbers)
private static IEnumerable<IDataRecord> CreateSqlDataRecordList(IDbCommand command, IEnumerable<int> numbers)
{
if (command is System.Data.SqlClient.SqlCommand) return CreateSqlDataRecordList_SD(numbers);
if (command is Microsoft.Data.SqlClient.SqlCommand) return CreateSqlDataRecordList_MD(numbers);
throw new ArgumentException(nameof(command));
}
private static IEnumerable<IDataRecord> CreateSqlDataRecordList(IDbConnection connection, IEnumerable<int> numbers)
{
if (connection is System.Data.SqlClient.SqlConnection) return CreateSqlDataRecordList_SD(numbers);
if (connection is Microsoft.Data.SqlClient.SqlConnection) return CreateSqlDataRecordList_MD(numbers);
throw new ArgumentException(nameof(connection));
}
private static List<Microsoft.SqlServer.Server.SqlDataRecord> CreateSqlDataRecordList_SD(IEnumerable<int> numbers)
{
var number_list = new List<Microsoft.SqlServer.Server.SqlDataRecord>();
......@@ -60,7 +72,25 @@ private static List<Microsoft.SqlServer.Server.SqlDataRecord> CreateSqlDataRecor
return number_list;
}
private static List<Microsoft.Data.SqlClient.Server.SqlDataRecord> CreateSqlDataRecordList_MD(IEnumerable<int> numbers)
{
var number_list = new List<Microsoft.Data.SqlClient.Server.SqlDataRecord>();
// Create an SqlMetaData object that describes our table type.
Microsoft.Data.SqlClient.Server.SqlMetaData[] tvp_definition = { new Microsoft.Data.SqlClient.Server.SqlMetaData("n", SqlDbType.Int) };
foreach (int n in numbers)
{
// Create a new record, using the metadata array above.
var rec = new Microsoft.Data.SqlClient.Server.SqlDataRecord(tvp_definition);
rec.SetInt32(0, n); // Set the value.
number_list.Add(rec); // Add it to the list.
}
return number_list;
}
private class IntDynamicParam : SqlMapper.IDynamicParameters
{
......@@ -72,16 +102,11 @@ public IntDynamicParam(IEnumerable<int> numbers)
public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
var sqlCommand = (System.Data.SqlClient.SqlCommand)command;
sqlCommand.CommandType = CommandType.StoredProcedure;
command.CommandType = CommandType.StoredProcedure;
var number_list = CreateSqlDataRecordList(numbers);
var number_list = CreateSqlDataRecordList(command, numbers);
// Add the table parameter.
var p = sqlCommand.Parameters.Add("ints", SqlDbType.Structured);
p.Direction = ParameterDirection.Input;
p.TypeName = "int_list_type";
p.Value = number_list;
AddStructured(command, number_list);
}
}
......@@ -95,17 +120,35 @@ public IntCustomParam(IEnumerable<int> numbers)
public void AddParameter(IDbCommand command, string name)
{
var sqlCommand = (System.Data.SqlClient.SqlCommand)command;
sqlCommand.CommandType = CommandType.StoredProcedure;
command.CommandType = CommandType.StoredProcedure;
var number_list = CreateSqlDataRecordList(numbers);
var number_list = CreateSqlDataRecordList(command, numbers);
// Add the table parameter.
var p = sqlCommand.Parameters.Add(name, SqlDbType.Structured);
AddStructured(command, number_list);
}
}
private static IDbDataParameter AddStructured(IDbCommand command, object value)
{
if (command is System.Data.SqlClient.SqlCommand sdcmd)
{
var p = sdcmd.Parameters.Add("integers", SqlDbType.Structured);
p.Direction = ParameterDirection.Input;
p.TypeName = "int_list_type";
p.Value = number_list;
p.Value = value;
return p;
}
else if (command is Microsoft.Data.SqlClient.SqlCommand mdcmd)
{
var p = mdcmd.Parameters.Add("integers", SqlDbType.Structured);
p.Direction = ParameterDirection.Input;
p.TypeName = "int_list_type";
p.Value = value;
return p;
}
else
throw new ArgumentException(nameof(command));
}
/* TODO:
......@@ -286,7 +329,7 @@ public void TestTVP()
try
{
connection.Execute("CREATE TYPE int_list_type AS TABLE (n int NOT NULL PRIMARY KEY)");
connection.Execute("CREATE PROC get_ints @ints int_list_type READONLY AS select * from @ints");
connection.Execute("CREATE PROC get_ints @integers int_list_type READONLY AS select * from @integers");
var nums = connection.Query<int>("get_ints", new IntDynamicParam(new int[] { 1, 2, 3 })).ToList();
Assert.Equal(1, nums[0]);
......@@ -298,11 +341,11 @@ public void TestTVP()
{
try
{
connection.Execute("DROP PROC get_ints");
try { connection.Execute("DROP PROC get_ints"); } catch { }
}
finally
{
connection.Execute("DROP TYPE int_list_type");
try { connection.Execute("DROP TYPE int_list_type"); } catch { }
}
}
}
......@@ -319,16 +362,12 @@ public new void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
base.AddParameters(command, identity);
var sqlCommand = (System.Data.SqlClient.SqlCommand)command;
sqlCommand.CommandType = CommandType.StoredProcedure;
command.CommandType = CommandType.StoredProcedure;
var number_list = CreateSqlDataRecordList(numbers);
var number_list = CreateSqlDataRecordList(command, numbers);
// Add the table parameter.
var p = sqlCommand.Parameters.Add("ints", SqlDbType.Structured);
p.Direction = ParameterDirection.Input;
p.TypeName = "int_list_type";
p.Value = number_list;
AddStructured(command, number_list);
}
}
......@@ -338,7 +377,7 @@ public void TestTVPWithAdditionalParams()
try
{
connection.Execute("CREATE TYPE int_list_type AS TABLE (n int NOT NULL PRIMARY KEY)");
connection.Execute("CREATE PROC get_values @ints int_list_type READONLY, @stringParam varchar(20), @dateParam datetime AS select i.*, @stringParam as stringParam, @dateParam as dateParam from @ints i");
connection.Execute("CREATE PROC get_values @integers int_list_type READONLY, @stringParam varchar(20), @dateParam datetime AS select i.*, @stringParam as stringParam, @dateParam as dateParam from @integers i");
var dynamicParameters = new DynamicParameterWithIntTVP(new int[] { 1, 2, 3 });
dynamicParameters.AddDynamicParams(new { stringParam = "stringParam", dateParam = new DateTime(2012, 1, 1) });
......@@ -374,7 +413,7 @@ public void TestSqlDataRecordListParametersWithAsTableValuedParameter()
connection.Execute("CREATE TYPE int_list_type AS TABLE (n int NOT NULL PRIMARY KEY)");
connection.Execute("CREATE PROC get_ints @integers int_list_type READONLY AS select * from @integers");
var records = CreateSqlDataRecordList(new int[] { 1, 2, 3 });
var records = CreateSqlDataRecordList(connection, new int[] { 1, 2, 3 });
var nums = connection.Query<int>("get_ints", new { integers = records.AsTableValuedParameter() }, commandType: CommandType.StoredProcedure).ToList();
Assert.Equal(new int[] { 1, 2, 3 }, nums);
......@@ -414,7 +453,7 @@ public void TestEmptySqlDataRecordListParametersWithAsTableValuedParameter()
connection.Execute("CREATE PROC get_ints @integers int_list_type READONLY AS select * from @integers");
var emptyRecord = CreateSqlDataRecordList(Enumerable.Empty<int>());
var emptyRecord = CreateSqlDataRecordList(connection, Enumerable.Empty<int>());
var nums = connection.Query<int>("get_ints", new { integers = emptyRecord.AsTableValuedParameter() }, commandType: CommandType.StoredProcedure).ToList();
Assert.True(nums.Count == 0);
......@@ -441,14 +480,28 @@ public void TestSqlDataRecordListParametersWithTypeHandlers()
connection.Execute("CREATE PROC get_ints @integers int_list_type READONLY AS select * from @integers");
// Variable type has to be IEnumerable<SqlDataRecord> for TypeHandler to kick in.
IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord> records = CreateSqlDataRecordList(new int[] { 1, 2, 3 });
object args;
if (connection is System.Data.SqlClient.SqlConnection)
{
IEnumerable<Microsoft.SqlServer.Server.SqlDataRecord> records = CreateSqlDataRecordList_SD(new int[] { 1, 2, 3 });
args = new { integers = records };
}
else if (connection is Microsoft.Data.SqlClient.SqlConnection)
{
IEnumerable<Microsoft.Data.SqlClient.Server.SqlDataRecord> records = CreateSqlDataRecordList_MD(new int[] { 1, 2, 3 });
args = new { integers = records };
}
else
{
throw new ArgumentException(nameof(connection));
}
var nums = connection.Query<int>("get_ints", new { integers = records }, commandType: CommandType.StoredProcedure).ToList();
var nums = connection.Query<int>("get_ints", args, commandType: CommandType.StoredProcedure).ToList();
Assert.Equal(new int[] { 1, 2, 3 }, nums);
try
{
connection.Query<int>("select * from @integers", new { integers = records }).First();
connection.Query<int>("select * from @integers", args).First();
throw new InvalidOperationException();
}
catch (Exception ex)
......@@ -665,6 +718,8 @@ private class HazSqlGeo
[Fact]
public void DBGeography_SO24405645_SO24402424()
{
SkipIfMsDataClient();
EntityFramework.Handlers.Register();
connection.Execute("create table #Geo (id int, geo geography, geometry geometry)");
......@@ -686,6 +741,8 @@ public void DBGeography_SO24405645_SO24402424()
[Fact]
public void SqlGeography_SO25538154()
{
SkipIfMsDataClient();
SqlMapper.ResetTypeHandlers();
connection.Execute("create table #SqlGeo (id int, geo geography, geometry geometry)");
......@@ -724,6 +781,8 @@ public void NullableSqlGeometry()
[Fact]
public void SqlHierarchyId_SO18888911()
{
SkipIfMsDataClient();
SqlMapper.ResetTypeHandlers();
var row = connection.Query<HazSqlHierarchy>("select 3 as [Id], hierarchyid::Parse('/1/2/3/') as [Path]").Single();
Assert.Equal(3, row.Id);
......
......@@ -6,8 +6,10 @@
namespace Dapper.Tests
{
[Collection("ProcedureTests")]
public sealed class SystemSqlClientProcedureTests : ProcedureTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("ProcedureTests")]
public sealed class MicrosoftSqlClientProcedureTests : ProcedureTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class ProcedureTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
......@@ -22,6 +22,8 @@ public EntityFrameworkTests()
[Fact]
public void Issue570_DbGeo_HasValues()
{
SkipIfMsDataClient();
EntityFramework.Handlers.Register();
const string redmond = "POINT (-122.1215 47.6740)";
DbGeography point = DbGeography.PointFromText(redmond, DbGeography.DefaultCoordinateSystemId);
......@@ -37,6 +39,8 @@ public void Issue570_DbGeo_HasValues()
[Fact]
public void Issue22_ExecuteScalar_EntityFramework()
{
SkipIfMsDataClient();
var geo = DbGeography.LineFromText("LINESTRING(-122.360 47.656, -122.343 47.656 )", 4326);
var geo2 = connection.ExecuteScalar<DbGeography>("select @geo", new { geo });
Assert.NotNull(geo2);
......
......@@ -6,8 +6,10 @@
namespace Dapper.Tests
{
[Collection("QueryMultipleTests")]
public sealed class SystemSqlClientQueryMultipleTests : QueryMultipleTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("QueryMultipleTests")]
public sealed class MicrosoftSqlClientQueryMultipleTests : QueryMultipleTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class QueryMultipleTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
......@@ -81,6 +81,9 @@ public sealed class MicrosoftSqlClientProvider : SqlServerDatabaseProvider
public abstract class TestBase<TProvider> : IDisposable where TProvider : DatabaseProvider
{
protected void SkipIfMsDataClient()
=> Skip.If<Microsoft.Data.SqlClient.SqlConnection>(connection);
protected DbConnection GetOpenConnection() => Provider.GetOpenConnection();
protected DbConnection GetClosedConnection() => Provider.GetClosedConnection();
protected DbConnection _connection;
......
......@@ -7,8 +7,10 @@
namespace Dapper.Tests
{
[Collection("TransactionTests")]
public sealed class SystemSqlClientTransactionTests : TransactionTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("TransactionTests")]
public sealed class MicrosoftSqlClientTransactionTests : TransactionTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class TransactionTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
......@@ -3,8 +3,10 @@
namespace Dapper.Tests
{
[Collection("TupleTests")]
public sealed class SystemSqlClientTupleTests : TupleTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("TupleTests")]
public sealed class MicrosoftSqlClientTupleTests : TupleTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class TupleTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
......@@ -4,8 +4,10 @@
namespace Dapper.Tests
{
[Collection("XmlTests")]
public sealed class SystemSqlClientXmlTests : XmlTests<SystemSqlClientProvider> { }
#if MSSQLCLIENT
[Collection("XmlTests")]
public sealed class MicrosoftSqlClientXmlTests : XmlTests<MicrosoftSqlClientProvider> { }
#endif
public abstract class XmlTests<TProvider> : TestBase<TProvider> where TProvider : DatabaseProvider
......
......@@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
appveyor.yml = appveyor.yml
build.ps1 = build.ps1
Directory.build.props = Directory.build.props
global.json = global.json
docs\index.md = docs\index.md
License.txt = License.txt
nuget.config = nuget.config
......
......@@ -5,32 +5,10 @@
<Title>Dapper</Title>
<Description>A high performance Micro-ORM supporting SQL Server, MySQL, Sqlite, SqlCE, Firebird etc..</Description>
<Authors>Sam Saffron;Marc Gravell;Nick Craver</Authors>
<TargetFrameworks>net451;netstandard1.3;netstandard2.0;netcoreapp2.1</TargetFrameworks>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net451'">
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' OR '$(TargetFramework)' == 'netstandard2.0'">
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.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-->
<!--<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" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<PackageReference Include="System.Collections.Concurrent" Version="4.3.0" />
<PackageReference Include="System.Collections.NonGeneric" Version="4.3.0" />
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
<PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
</ItemGroup>
</Project>
using System;
using System.Data;
#if !NETSTANDARD1_3
namespace Dapper
{
internal sealed class DataTableHandler : SqlMapper.ITypeHandler
......@@ -16,4 +15,3 @@ public void SetValue(IDbDataParameter parameter, object value)
}
}
}
#endif
\ No newline at end of file
......@@ -26,27 +26,11 @@ public DefaultTypeMap(Type type)
Properties = GetSettableProps(type);
_type = type;
}
#if NETSTANDARD1_3
private static bool IsParameterMatch(ParameterInfo[] x, ParameterInfo[] y)
{
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
if (x.Length != y.Length) return false;
for (int i = 0; i < x.Length; i++)
if (x[i].ParameterType != y[i].ParameterType) return false;
return true;
}
#endif
internal static MethodInfo GetPropertySetter(PropertyInfo propertyInfo, Type type)
{
if (propertyInfo.DeclaringType == type) return propertyInfo.GetSetMethod(true);
#if NETSTANDARD1_3
return propertyInfo.DeclaringType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Single(x => x.Name == propertyInfo.Name
&& x.PropertyType == propertyInfo.PropertyType
&& IsParameterMatch(x.GetIndexParameters(), propertyInfo.GetIndexParameters())
).GetSetMethod(true);
#else
return propertyInfo.DeclaringType.GetProperty(
propertyInfo.Name,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
......@@ -54,7 +38,6 @@ internal static MethodInfo GetPropertySetter(PropertyInfo propertyInfo, Type typ
propertyInfo.PropertyType,
propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray(),
null).GetSetMethod(true);
#endif
}
internal static List<PropertyInfo> GetSettableProps(Type t)
......@@ -97,9 +80,9 @@ public ConstructorInfo FindConstructor(string[] names, Type[] types)
continue;
var unboxedType = Nullable.GetUnderlyingType(ctorParameters[i].ParameterType) ?? ctorParameters[i].ParameterType;
if ((unboxedType != types[i] && !SqlMapper.HasTypeHandler(unboxedType))
&& !(unboxedType.IsEnum() && Enum.GetUnderlyingType(unboxedType) == types[i])
&& !(unboxedType.IsEnum && Enum.GetUnderlyingType(unboxedType) == types[i])
&& !(unboxedType == typeof(char) && types[i] == typeof(string))
&& !(unboxedType.IsEnum() && types[i] == typeof(string)))
&& !(unboxedType.IsEnum && types[i] == typeof(string)))
{
break;
}
......@@ -118,11 +101,7 @@ public ConstructorInfo FindConstructor(string[] names, Type[] types)
public ConstructorInfo FindExplicitConstructor()
{
var constructors = _type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
#if NETSTANDARD1_3
var withAttr = constructors.Where(c => c.CustomAttributes.Any(x => x.AttributeType == typeof(ExplicitConstructorAttribute))).ToList();
#else
var withAttr = constructors.Where(c => c.GetCustomAttributes(typeof(ExplicitConstructorAttribute), true).Length > 0).ToList();
#endif
if (withAttr.Count == 1)
{
......
......@@ -6,10 +6,6 @@
using System.Reflection;
using System.Reflection.Emit;
#if NETSTANDARD1_3
using ApplicationException = System.InvalidOperationException;
#endif
namespace Dapper
{
/// <summary>
......
......@@ -5,9 +5,7 @@
namespace Dapper
{
internal sealed class SqlDataRecordHandler<T> : SqlMapper.ITypeHandler
#if !NETSTANDARD1_3
where T : IDataRecord
#endif
{
public object Parse(Type destinationType, object value)
{
......
......@@ -12,9 +12,7 @@ namespace Dapper
/// Used to pass a IEnumerable&lt;SqlDataRecord&gt; as a SqlDataRecordListTVPParameter
/// </summary>
internal sealed class SqlDataRecordListTVPParameter<T> : SqlMapper.ICustomQueryParameter
#if !NETSTANDARD1_3
where T : IDataRecord
#endif
{
private readonly IEnumerable<T> data;
private readonly string typeName;
......
......@@ -406,7 +406,7 @@ private static DbCommand TrySetupAsyncCommand(this CommandDefinition command, ID
private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn, Type effectiveType, CommandDefinition command)
{
object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType(), null);
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType());
var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed;
var cancel = command.CancellationToken;
......@@ -470,7 +470,7 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn,
private static async Task<T> QueryRowAsync<T>(this IDbConnection cnn, Row row, Type effectiveType, CommandDefinition command)
{
object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType(), null);
var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType());
var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed;
var cancel = command.CancellationToken;
......@@ -594,7 +594,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
isFirst = false;
cmd = command.TrySetupAsyncCommand(cnn, null);
masterSql = cmd.CommandText;
var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null);
var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType());
info = GetCacheInfo(identity, obj, command.AddToCache);
}
else if (pending.Count >= MAX_PENDING)
......@@ -642,7 +642,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
{
masterSql = cmd.CommandText;
isFirst = false;
var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType(), null);
var identity = new Identity(command.CommandText, cmd.CommandType, cnn, null, obj.GetType());
info = GetCacheInfo(identity, obj, command.AddToCache);
}
else
......@@ -667,7 +667,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, object param)
{
var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param?.GetType(), null);
var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param?.GetType());
var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed;
using (var cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader))
......@@ -935,7 +935,7 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
private static async Task<IEnumerable<TReturn>> MultiMapAsync<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, CommandDefinition command, Delegate map, string splitOn)
{
object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(TFirst), param?.GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) });
var identity = new Identity<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh>(command.CommandText, command.CommandType, cnn, typeof(TFirst), param?.GetType());
var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed;
try
......@@ -985,7 +985,7 @@ private static async Task<IEnumerable<TReturn>> MultiMapAsync<TReturn>(this IDbC
}
object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, types[0], param?.GetType(), types);
var identity = new IdentityWithTypes(command.CommandText, command.CommandType, cnn, types[0], param?.GetType(), types);
var info = GetCacheInfo(identity, param, command.AddToCache);
bool wasClosed = cnn.State == ConnectionState.Closed;
try
......@@ -1037,7 +1037,7 @@ private static IEnumerable<T> ExecuteReaderSync<T>(IDataReader reader, Func<IDat
public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn, CommandDefinition command)
{
object param = command.Parameters;
var identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param?.GetType(), null);
var identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param?.GetType());
CacheInfo info = GetCacheInfo(identity, param, command.AddToCache);
DbCommand cmd = null;
......@@ -1233,7 +1233,7 @@ private static async Task<T> ExecuteScalarImplAsync<T>(IDbConnection cnn, Comman
object param = command.Parameters;
if (param != null)
{
var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType(), null);
var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType());
paramReader = GetCacheInfo(identity, command.Parameters, command.AddToCache).ParamReader;
}
......
#if !NETSTANDARD1_3 // needs the component-model API
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
......@@ -104,4 +103,3 @@ public override void SetValue(object component, object value)
}
}
}
#endif
......@@ -204,15 +204,7 @@ private T ReadRow<T>(Type type, Row row)
private IEnumerable<TReturn> MultiReadInternal<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(Delegate func, string splitOn)
{
var identity = this.identity.ForGrid(typeof(TReturn), new Type[] {
typeof(TFirst),
typeof(TSecond),
typeof(TThird),
typeof(TFourth),
typeof(TFifth),
typeof(TSixth),
typeof(TSeventh)
}, gridIndex);
var identity = this.identity.ForGrid<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh>(typeof(TReturn), gridIndex);
IsConsumed = true;
......
......@@ -140,7 +140,7 @@ public static IEnumerable<dynamic> Parse(this IDataReader reader)
{
concreteType = concreteType ?? typeof(T);
var func = GetDeserializer(concreteType, reader, startIndex, length, returnNullIfFirstMissing);
if (concreteType.IsValueType())
if (concreteType.IsValueType)
{
return _ => (T)func(_);
}
......
using System;
using System.Data;
using System.Runtime.CompilerServices;
namespace Dapper
{
public static partial class SqlMapper
{
internal sealed class Identity<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh> : Identity
{
private static readonly int s_typeHash;
private static readonly int s_typeCount = CountNonTrivial(out s_typeHash);
internal Identity(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, int gridIndex = 0)
: base(sql, commandType, connectionString, type, parametersType, s_typeHash, gridIndex)
{}
internal Identity(string sql, CommandType? commandType, IDbConnection connection, Type type, Type parametersType, int gridIndex = 0)
: base(sql, commandType, connection.ConnectionString, type, parametersType, s_typeHash, gridIndex)
{ }
static int CountNonTrivial(out int hashCode)
{
int hashCodeLocal = 0;
int count = 0;
bool Map<T>()
{
if(typeof(T) != typeof(DontMap))
{
count++;
hashCodeLocal = (hashCodeLocal * 23) + (typeof(T).GetHashCode());
return true;
}
return false;
}
_ = Map<TFirst>() && Map<TSecond>() && Map<TThird>()
&& Map<TFourth>() && Map<TFifth>() && Map<TSixth>()
&& Map<TSeventh>();
hashCode = hashCodeLocal;
return count;
}
internal override int TypeCount => s_typeCount;
internal override Type GetType(int index)
{
switch (index)
{
case 0: return typeof(TFirst);
case 1: return typeof(TSecond);
case 2: return typeof(TThird);
case 3: return typeof(TFourth);
case 4: return typeof(TFifth);
case 5: return typeof(TSixth);
case 6: return typeof(TSeventh);
default: return base.GetType(index);
}
}
}
internal sealed class IdentityWithTypes : Identity
{
private readonly Type[] _types;
internal IdentityWithTypes(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, Type[] otherTypes, int gridIndex = 0)
: base(sql, commandType, connectionString, type, parametersType, HashTypes(otherTypes), gridIndex)
{
_types = otherTypes ?? Type.EmptyTypes;
}
internal IdentityWithTypes(string sql, CommandType? commandType, IDbConnection connection, Type type, Type parametersType, Type[] otherTypes, int gridIndex = 0)
: base(sql, commandType, connection.ConnectionString, type, parametersType, HashTypes(otherTypes), gridIndex)
{
_types = otherTypes ?? Type.EmptyTypes;
}
internal override int TypeCount => _types.Length;
internal override Type GetType(int index) => _types[index];
static int HashTypes(Type[] types)
{
var hashCode = 0;
if (types != null)
{
foreach (var t in types)
{
hashCode = (hashCode * 23) + (t?.GetHashCode() ?? 0);
}
}
return hashCode;
}
}
/// <summary>
/// Identity of a cached query in Dapper, used for extensibility.
/// </summary>
public class Identity : IEquatable<Identity>
{
internal virtual int TypeCount => 0;
internal virtual Type GetType(int index) => throw new IndexOutOfRangeException(nameof(index));
internal Identity ForGrid<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh>(Type primaryType, int gridIndex) =>
new Identity<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh>(sql, commandType, connectionString, primaryType, parametersType, gridIndex);
internal Identity ForGrid(Type primaryType, int gridIndex) =>
new Identity(sql, commandType, connectionString, primaryType, parametersType, null, gridIndex);
new Identity(sql, commandType, connectionString, primaryType, parametersType, 0, gridIndex);
internal Identity ForGrid(Type primaryType, Type[] otherTypes, int gridIndex) =>
new Identity(sql, commandType, connectionString, primaryType, parametersType, otherTypes, gridIndex);
(otherTypes == null || otherTypes.Length == 0)
? new Identity(sql, commandType, connectionString, primaryType, parametersType, 0, gridIndex)
: new IdentityWithTypes(sql, commandType, connectionString, primaryType, parametersType, otherTypes, gridIndex);
/// <summary>
/// Create an identity for use with DynamicParameters, internal use only.
......@@ -22,12 +113,12 @@ public class Identity : IEquatable<Identity>
/// <param name="type">The parameters type to create an <see cref="Identity"/> for.</param>
/// <returns></returns>
public Identity ForDynamicParameters(Type type) =>
new Identity(sql, commandType, connectionString, this.type, type, null, -1);
new Identity(sql, commandType, connectionString, this.type, type, 0, -1);
internal Identity(string sql, CommandType? commandType, IDbConnection connection, Type type, Type parametersType, Type[] otherTypes)
: this(sql, commandType, connection.ConnectionString, type, parametersType, otherTypes, 0) { /* base call */ }
internal Identity(string sql, CommandType? commandType, IDbConnection connection, Type type, Type parametersType)
: this(sql, commandType, connection.ConnectionString, type, parametersType, 0, 0) { /* base call */ }
private Identity(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, Type[] otherTypes, int gridIndex)
private protected Identity(string sql, CommandType? commandType, string connectionString, Type type, Type parametersType, int otherTypesHash, int gridIndex)
{
this.sql = sql;
this.commandType = commandType;
......@@ -42,13 +133,7 @@ private Identity(string sql, CommandType? commandType, string connectionString,
hashCode = (hashCode * 23) + gridIndex.GetHashCode();
hashCode = (hashCode * 23) + (sql?.GetHashCode() ?? 0);
hashCode = (hashCode * 23) + (type?.GetHashCode() ?? 0);
if (otherTypes != null)
{
foreach (var t in otherTypes)
{
hashCode = (hashCode * 23) + (t?.GetHashCode() ?? 0);
}
}
hashCode = (hashCode * 23) + otherTypesHash;
hashCode = (hashCode * 23) + (connectionString == null ? 0 : connectionStringComparer.GetHashCode(connectionString));
hashCode = (hashCode * 23) + (parametersType?.GetHashCode() ?? 0);
}
......@@ -101,6 +186,11 @@ private Identity(string sql, CommandType? commandType, string connectionString,
/// <returns></returns>
public override int GetHashCode() => hashCode;
/// <summary>
/// See object.ToString()
/// </summary>
public override string ToString() => sql;
/// <summary>
/// Compare 2 Identity objects
/// </summary>
......@@ -108,13 +198,30 @@ private Identity(string sql, CommandType? commandType, string connectionString,
/// <returns>Whether the two are equal</returns>
public bool Equals(Identity other)
{
return other != null
&& gridIndex == other.gridIndex
if (ReferenceEquals(this, other)) return true;
if (ReferenceEquals(other, null)) return false;
int typeCount;
return gridIndex == other.gridIndex
&& type == other.type
&& sql == other.sql
&& commandType == other.commandType
&& connectionStringComparer.Equals(connectionString, other.connectionString)
&& parametersType == other.parametersType;
&& parametersType == other.parametersType
&& (typeCount = TypeCount) == other.TypeCount
&& (typeCount == 0 || TypesEqual(this, other, typeCount));
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool TypesEqual(Identity x, Identity y, int count)
{
if (y.TypeCount != count) return false;
for(int i = 0; i < count; i++)
{
if (x.GetType(i) != y.GetType(i))
return false;
}
return true;
}
}
}
......
......@@ -11,9 +11,7 @@ public static partial class SqlMapper
/// </summary>
/// <typeparam name="T">The type to have a cache for.</typeparam>
[Obsolete(ObsoleteInternalUsageOnly, false)]
#if !NETSTANDARD1_3
[Browsable(false)]
#endif
[EditorBrowsable(EditorBrowsableState.Never)]
public static class TypeHandlerCache<T>
{
......
此差异已折叠。
using System.Data;
#if !NETSTANDARD1_3
namespace Dapper
{
/// <summary>
......@@ -49,4 +48,3 @@ internal static void Set(IDbDataParameter parameter, DataTable table, string typ
}
}
}
#endif
using System;
using System.Reflection;
using System.Collections.Generic;
namespace Dapper
{
internal static class TypeExtensions
{
public static string Name(this Type type) =>
#if NETSTANDARD1_3 || NETCOREAPP1_0
type.GetTypeInfo().Name;
#else
type.Name;
#endif
public static bool IsValueType(this Type type) =>
#if NETSTANDARD1_3 || NETCOREAPP1_0
type.GetTypeInfo().IsValueType;
#else
type.IsValueType;
#endif
public static bool IsEnum(this Type type) =>
#if NETSTANDARD1_3 || NETCOREAPP1_0
type.GetTypeInfo().IsEnum;
#else
type.IsEnum;
#endif
public static bool IsGenericType(this Type type) =>
#if NETSTANDARD1_3 || NETCOREAPP1_0
type.GetTypeInfo().IsGenericType;
#else
type.IsGenericType;
#endif
public static bool IsInterface(this Type type) =>
#if NETSTANDARD1_3 || NETCOREAPP1_0
type.GetTypeInfo().IsInterface;
#else
type.IsInterface;
#endif
#if NETSTANDARD1_3 || NETCOREAPP1_0
public static IEnumerable<Attribute> GetCustomAttributes(this Type type, bool inherit)
{
return type.GetTypeInfo().GetCustomAttributes(inherit);
}
public static TypeCode GetTypeCode(Type type)
{
if (type == null) return TypeCode.Empty;
if (typeCodeLookup.TryGetValue(type, out TypeCode result)) return result;
if (type.IsEnum())
{
type = Enum.GetUnderlyingType(type);
if (typeCodeLookup.TryGetValue(type, out result)) return result;
}
return TypeCode.Object;
}
private static readonly Dictionary<Type, TypeCode> typeCodeLookup = new Dictionary<Type, TypeCode>
{
[typeof(bool)] = TypeCode.Boolean,
[typeof(byte)] = TypeCode.Byte,
[typeof(char)] = TypeCode.Char,
[typeof(DateTime)] = TypeCode.DateTime,
[typeof(decimal)] = TypeCode.Decimal,
[typeof(double)] = TypeCode.Double,
[typeof(short)] = TypeCode.Int16,
[typeof(int)] = TypeCode.Int32,
[typeof(long)] = TypeCode.Int64,
[typeof(object)] = TypeCode.Object,
[typeof(sbyte)] = TypeCode.SByte,
[typeof(float)] = TypeCode.Single,
[typeof(string)] = TypeCode.String,
[typeof(ushort)] = TypeCode.UInt16,
[typeof(uint)] = TypeCode.UInt32,
[typeof(ulong)] = TypeCode.UInt64,
};
#else
public static TypeCode GetTypeCode(Type type) => Type.GetTypeCode(type);
#endif
public static MethodInfo GetPublicInstanceMethod(this Type type, string name, Type[] types)
{
#if NETSTANDARD1_3 || NETCOREAPP1_0
var method = type.GetMethod(name, types);
return (method?.IsPublic == true && !method.IsStatic) ? method : null;
#else
return type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public, null, types, null);
#endif
}
=> type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public, null, types, null);
}
}
......@@ -5,7 +5,6 @@ namespace Dapper
{
public static partial class SqlMapper
{
#if !NETSTANDARD1_3 && !NETSTANDARD2_0
/// <summary>
/// A type handler for data-types that are supported by the underlying provider, but which need
/// a well-known UdtTypeName to be specified
......@@ -36,6 +35,5 @@ void ITypeHandler.SetValue(IDbDataParameter parameter, object value)
if(!(value is DBNull)) StructuredHelper.ConfigureUDT(parameter, udtTypeName);
}
}
#endif
}
}
......@@ -17,7 +17,7 @@
<DebugType>embedded</DebugType>
<DefaultLanguage>en-US</DefaultLanguage>
<IncludeSymbols>false</IncludeSymbols>
<xUnitVersion>2.4.1-pre.build.4059</xUnitVersion>
<xUnitVersion>2.4.1</xUnitVersion>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net451'">
......@@ -25,7 +25,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="2.2.13" PrivateAssets="all" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.0.25" PrivateAssets="all" />
<PackageReference Include="SourceLink.Create.GitHub" Version="2.8.3" PrivateAssets="All" />
<DotNetCliToolReference Include="dotnet-sourcelink" Version="2.8.3" />
<DotNetCliToolReference Include="dotnet-sourcelink-git" Version="2.8.3" />
......
{
"version": "1.60",
"assemblyVersion": "1.60.0.0",
"version": "2.0-preview1",
"assemblyVersion": "2.0.0.0",
"publicReleaseRefSpec": [
"^refs/heads/master$",
"^refs/tags/v\\d+\\.\\d+"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册