Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add .NET 4.5 specific project to support Task Based Async calls #49

Closed
wants to merge 5 commits into from

4 participants

bkaid Marc Gravell brannon Anton Heryanto Hasan
bkaid

Added a QueryAsync method using .NET 4.5 style task based async call to ExecuteReaderAsync. Updated .nuspec file to include a .NET 4.5 library. Currently SQL server specific because SqlCommand defines ExecuteReaderAsync (not IDbCommand).

bkaid bkaid Added .NET 4.5 style QueryAsync method to support asynchronous databa…
…se calls.

Requires SQL Server because ExecuteReaderAsync is defined on SqlCommand and not IDbCommand.
3fccaa6
Marc Gravell
Owner

Actually, this is defined on the DbCommand: http://msdn.microsoft.com/en-us/library/hh223695.aspx - if possible, the least-specific version is preferable; however, I think this is more complex than first appears. In particular, I've got consideration towards things that decorate the command pattern (mini-profiler etc). We might need to invest a bit of time thinking about how we do this correctly in the more general context. I imagine a task with continuation would do it.

I think jumping on the sql-server one would be a bit of a mistake, long-term. Might be better to hold on this for now, pending more investigation.

I am perfectly open to a new 4.5-specific build; that doesn't bother me.

bkaid

Thanks Marc - didn't catch that it was available on DbCommand. I updated my fork to use DbCommand instead of SqlCommand.

This attempt was as good as I could do. You and Sam are the experts here so I'll let you guys figure out the best approach. But it would be great if Dapper had built-in support for async querying.

brannon

+1 for Async support.

Anton Heryanto Hasan

:+1: Async support too

Marc Gravell
Owner

I've merged this; thanks! Note: was a manual merge (conflicts etc), but seems to work. My preference would be to drag this into the core dll for 4.5, rather than a second nuget package - any thoughts on that? Have a look at the merged base and let me know.

Marc Gravell mgravell closed this
bkaid

Thanks Marc. I agree it would be great to have in the core nuget package and once its available I'll update the notes on my dapper-async nuget to indicate that the package is deprecated since the functionality has been moved to core dapper package.

oceangu2010 oceangu2010 referenced this pull request from a commit in oceangu2010/drapper
Marc Gravell mgravell Async; manual merge of StackExchange/dapper-dot-net#49
- huge thanks to bkaid
37329c8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 9, 2012
  1. bkaid

    Added .NET 4.5 style QueryAsync method to support asynchronous databa…

    bkaid authored
    …se calls.
    
    Requires SQL Server because ExecuteReaderAsync is defined on SqlCommand and not IDbCommand.
Commits on Sep 11, 2012
  1. bkaid
Commits on Sep 14, 2012
  1. bkaid

    Added async versions of Query methods that do multi-mapping like Quer…

    bkaid authored
    …yAsync<TFirst, TSecond, TReturn>
Commits on Oct 17, 2012
  1. bkaid
  2. bkaid
This page is out of date. Refresh to see the latest.
58 Dapper - VS2012.sln
View
@@ -5,17 +5,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper", "Dapper\Dapper.csp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DapperTests", "Tests\DapperTests.csproj", "{A2A80512-11F4-4028-A995-505463632C84}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper NET35", "Dapper NET35\Dapper NET35.csproj", "{B26305D8-3A89-4D68-A981-9BBF378B81FA}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper.Contrib", "Dapper.Contrib\Dapper.Contrib.csproj", "{C2FC4DF5-C8D1-4EA8-8E0C-85A3793EB0BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper.Contrib.Tests", "Dapper.Contrib.Tests\Dapper.Contrib.Tests.csproj", "{A4F4A06E-D179-4251-A232-AEF4CE9AD9B5}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DapperTests NET35", "DapperTests NET35\DapperTests NET35.csproj", "{3BAA9F79-BA0A-4092-B47B-20170DD47989}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper.SqlBuilder", "Dapper.SqlBuilder\Dapper.SqlBuilder.csproj", "{BF782EF1-2B0F-42FA-9DD0-928454A94C6D}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper.Rainbow", "Dapper.Rainbow\Dapper.Rainbow.csproj", "{21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper NET45", "Dapper NET45\Dapper NET45.csproj", "{EDD52209-45E8-42BA-81C1-D39FA1F07646}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DapperTests NET45", "DapperTests NET45\DapperTests NET45.csproj", "{B7B69EE5-0E0D-4218-88DF-79E7D2355D26}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{E043638B-9516-477C-A75A-254DD55D4113}"
ProjectSection(SolutionItems) = preProject
@@ -52,16 +50,6 @@ Global
{A2A80512-11F4-4028-A995-505463632C84}.Release|Mixed Platforms.Build.0 = Release|x86
{A2A80512-11F4-4028-A995-505463632C84}.Release|x86.ActiveCfg = Release|x86
{A2A80512-11F4-4028-A995-505463632C84}.Release|x86.Build.0 = Release|x86
- {B26305D8-3A89-4D68-A981-9BBF378B81FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B26305D8-3A89-4D68-A981-9BBF378B81FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B26305D8-3A89-4D68-A981-9BBF378B81FA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {B26305D8-3A89-4D68-A981-9BBF378B81FA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {B26305D8-3A89-4D68-A981-9BBF378B81FA}.Debug|x86.ActiveCfg = Debug|Any CPU
- {B26305D8-3A89-4D68-A981-9BBF378B81FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B26305D8-3A89-4D68-A981-9BBF378B81FA}.Release|Any CPU.Build.0 = Release|Any CPU
- {B26305D8-3A89-4D68-A981-9BBF378B81FA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {B26305D8-3A89-4D68-A981-9BBF378B81FA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {B26305D8-3A89-4D68-A981-9BBF378B81FA}.Release|x86.ActiveCfg = Release|Any CPU
{C2FC4DF5-C8D1-4EA8-8E0C-85A3793EB0BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2FC4DF5-C8D1-4EA8-8E0C-85A3793EB0BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2FC4DF5-C8D1-4EA8-8E0C-85A3793EB0BB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -82,16 +70,6 @@ Global
{A4F4A06E-D179-4251-A232-AEF4CE9AD9B5}.Release|Mixed Platforms.Build.0 = Release|x86
{A4F4A06E-D179-4251-A232-AEF4CE9AD9B5}.Release|x86.ActiveCfg = Release|x86
{A4F4A06E-D179-4251-A232-AEF4CE9AD9B5}.Release|x86.Build.0 = Release|x86
- {3BAA9F79-BA0A-4092-B47B-20170DD47989}.Debug|Any CPU.ActiveCfg = Debug|x86
- {3BAA9F79-BA0A-4092-B47B-20170DD47989}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
- {3BAA9F79-BA0A-4092-B47B-20170DD47989}.Debug|Mixed Platforms.Build.0 = Debug|x86
- {3BAA9F79-BA0A-4092-B47B-20170DD47989}.Debug|x86.ActiveCfg = Debug|x86
- {3BAA9F79-BA0A-4092-B47B-20170DD47989}.Debug|x86.Build.0 = Debug|x86
- {3BAA9F79-BA0A-4092-B47B-20170DD47989}.Release|Any CPU.ActiveCfg = Release|x86
- {3BAA9F79-BA0A-4092-B47B-20170DD47989}.Release|Mixed Platforms.ActiveCfg = Release|x86
- {3BAA9F79-BA0A-4092-B47B-20170DD47989}.Release|Mixed Platforms.Build.0 = Release|x86
- {3BAA9F79-BA0A-4092-B47B-20170DD47989}.Release|x86.ActiveCfg = Release|x86
- {3BAA9F79-BA0A-4092-B47B-20170DD47989}.Release|x86.Build.0 = Release|x86
{BF782EF1-2B0F-42FA-9DD0-928454A94C6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF782EF1-2B0F-42FA-9DD0-928454A94C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF782EF1-2B0F-42FA-9DD0-928454A94C6D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -102,16 +80,26 @@ Global
{BF782EF1-2B0F-42FA-9DD0-928454A94C6D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{BF782EF1-2B0F-42FA-9DD0-928454A94C6D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{BF782EF1-2B0F-42FA-9DD0-928454A94C6D}.Release|x86.ActiveCfg = Release|Any CPU
- {21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}.Debug|x86.ActiveCfg = Debug|Any CPU
- {21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}.Release|Any CPU.Build.0 = Release|Any CPU
- {21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
- {21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
- {21BC6EA8-3D10-4CC9-A1B3-9FAD59F7D1BB}.Release|x86.ActiveCfg = Release|Any CPU
+ {EDD52209-45E8-42BA-81C1-D39FA1F07646}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EDD52209-45E8-42BA-81C1-D39FA1F07646}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EDD52209-45E8-42BA-81C1-D39FA1F07646}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {EDD52209-45E8-42BA-81C1-D39FA1F07646}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {EDD52209-45E8-42BA-81C1-D39FA1F07646}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EDD52209-45E8-42BA-81C1-D39FA1F07646}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EDD52209-45E8-42BA-81C1-D39FA1F07646}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EDD52209-45E8-42BA-81C1-D39FA1F07646}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {EDD52209-45E8-42BA-81C1-D39FA1F07646}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {EDD52209-45E8-42BA-81C1-D39FA1F07646}.Release|x86.ActiveCfg = Release|Any CPU
+ {B7B69EE5-0E0D-4218-88DF-79E7D2355D26}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {B7B69EE5-0E0D-4218-88DF-79E7D2355D26}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {B7B69EE5-0E0D-4218-88DF-79E7D2355D26}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {B7B69EE5-0E0D-4218-88DF-79E7D2355D26}.Debug|x86.ActiveCfg = Debug|x86
+ {B7B69EE5-0E0D-4218-88DF-79E7D2355D26}.Debug|x86.Build.0 = Debug|x86
+ {B7B69EE5-0E0D-4218-88DF-79E7D2355D26}.Release|Any CPU.ActiveCfg = Release|x86
+ {B7B69EE5-0E0D-4218-88DF-79E7D2355D26}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {B7B69EE5-0E0D-4218-88DF-79E7D2355D26}.Release|Mixed Platforms.Build.0 = Release|x86
+ {B7B69EE5-0E0D-4218-88DF-79E7D2355D26}.Release|x86.ActiveCfg = Release|x86
+ {B7B69EE5-0E0D-4218-88DF-79E7D2355D26}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
57 Dapper NET45/Dapper NET45.csproj
View
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{EDD52209-45E8-42BA-81C1-D39FA1F07646}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Dapper</RootNamespace>
+ <AssemblyName>Dapper</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;CSHARP50</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE;CSHARP50</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Dapper\Properties\AssemblyInfo.cs">
+ <Link>AssemblyInfo.cs</Link>
+ </Compile>
+ <Compile Include="..\Dapper\SqlMapper.cs">
+ <Link>SqlMapper.cs</Link>
+ </Compile>
+ <Compile Include="SqlMapperAsync.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="Properties\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
198 Dapper NET45/SqlMapperAsync.cs
View
@@ -0,0 +1,198 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.Common;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Dapper
+{
+ public static partial class SqlMapper
+ {
+ /// <summary>
+ /// Execute a query asynchronously using .NET 4.5 Task.
+ /// </summary>
+ public static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
+ {
+ var identity = new Identity(sql, commandType, cnn, typeof(T), param == null ? null : param.GetType(), null);
+ var info = GetCacheInfo(identity);
+ var cmd = (DbCommand)SetupCommand(cnn, transaction, sql, info.ParamReader, param, commandTimeout, commandType);
+
+ using (var reader = await cmd.ExecuteReaderAsync())
+ {
+ return ExecuteReader<T>(reader, identity, info).ToList();
+ }
+ }
+
+ /// <summary>
+ /// Maps a query to objects
+ /// </summary>
+ /// <typeparam name="TFirst">The first type in the recordset</typeparam>
+ /// <typeparam name="TSecond">The second type in the recordset</typeparam>
+ /// <typeparam name="TReturn">The return type</typeparam>
+ /// <param name="cnn"></param>
+ /// <param name="sql"></param>
+ /// <param name="map"></param>
+ /// <param name="param"></param>
+ /// <param name="transaction"></param>
+ /// <param name="buffered"></param>
+ /// <param name="splitOn">The Field we should split and read the second object from (default: id)</param>
+ /// <param name="commandTimeout">Number of seconds before command execution timeout</param>
+ /// <param name="commandType">Is it a stored proc or a batch?</param>
+ /// <returns></returns>
+ public static async Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
+ {
+ return await MultiMapAsync<TFirst, TSecond, DontMap, DontMap, DontMap, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ }
+
+ /// <summary>
+ /// Maps a query to objects
+ /// </summary>
+ /// <typeparam name="TFirst"></typeparam>
+ /// <typeparam name="TSecond"></typeparam>
+ /// <typeparam name="TThird"></typeparam>
+ /// <typeparam name="TReturn"></typeparam>
+ /// <param name="cnn"></param>
+ /// <param name="sql"></param>
+ /// <param name="map"></param>
+ /// <param name="param"></param>
+ /// <param name="transaction"></param>
+ /// <param name="buffered"></param>
+ /// <param name="splitOn">The Field we should split and read the second object from (default: id)</param>
+ /// <param name="commandTimeout">Number of seconds before command execution timeout</param>
+ /// <param name="commandType"></param>
+ /// <returns></returns>
+ public static async Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
+ {
+ return await MultiMapAsync<TFirst, TSecond, TThird, DontMap, DontMap, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ }
+
+ /// <summary>
+ /// Perform a multi mapping query with 4 input parameters
+ /// </summary>
+ /// <typeparam name="TFirst"></typeparam>
+ /// <typeparam name="TSecond"></typeparam>
+ /// <typeparam name="TThird"></typeparam>
+ /// <typeparam name="TFourth"></typeparam>
+ /// <typeparam name="TReturn"></typeparam>
+ /// <param name="cnn"></param>
+ /// <param name="sql"></param>
+ /// <param name="map"></param>
+ /// <param name="param"></param>
+ /// <param name="transaction"></param>
+ /// <param name="buffered"></param>
+ /// <param name="splitOn"></param>
+ /// <param name="commandTimeout"></param>
+ /// <param name="commandType"></param>
+ /// <returns></returns>
+ public static async Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TFourth, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
+ {
+ return await MultiMapAsync<TFirst, TSecond, TThird, TFourth, DontMap, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ }
+
+ /// <summary>
+ /// Perform a multi mapping query with 5 input parameters
+ /// </summary>
+ /// <typeparam name="TFirst"></typeparam>
+ /// <typeparam name="TSecond"></typeparam>
+ /// <typeparam name="TThird"></typeparam>
+ /// <typeparam name="TFourth"></typeparam>
+ /// <typeparam name="TFifth"></typeparam>
+ /// <typeparam name="TReturn"></typeparam>
+ /// <param name="cnn"></param>
+ /// <param name="sql"></param>
+ /// <param name="map"></param>
+ /// <param name="param"></param>
+ /// <param name="transaction"></param>
+ /// <param name="buffered"></param>
+ /// <param name="splitOn"></param>
+ /// <param name="commandTimeout"></param>
+ /// <param name="commandType"></param>
+ /// <returns></returns>
+ public static async Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
+ {
+ return await MultiMapAsync<TFirst, TSecond, TThird, TFourth, TFifth, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ }
+
+ /// <summary>
+ /// Perform a multi mapping query with 6 input parameters
+ /// </summary>
+ /// <typeparam name="TFirst"></typeparam>
+ /// <typeparam name="TSecond"></typeparam>
+ /// <typeparam name="TThird"></typeparam>
+ /// <typeparam name="TFourth"></typeparam>
+ /// <typeparam name="TFifth"></typeparam>
+ /// <typeparam name="TSixth"></typeparam>
+ /// <typeparam name="TReturn"></typeparam>
+ /// <param name="cnn"></param>
+ /// <param name="sql"></param>
+ /// <param name="map"></param>
+ /// <param name="param"></param>
+ /// <param name="transaction"></param>
+ /// <param name="buffered"></param>
+ /// <param name="splitOn"></param>
+ /// <param name="commandTimeout"></param>
+ /// <param name="commandType"></param>
+ /// <returns></returns>
+ public static async Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
+ {
+ return await MultiMapAsync<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ }
+
+ /// <summary>
+ /// Perform a multi mapping query with 7 input parameters
+ /// </summary>
+ /// <typeparam name="TFirst"></typeparam>
+ /// <typeparam name="TSecond"></typeparam>
+ /// <typeparam name="TThird"></typeparam>
+ /// <typeparam name="TFourth"></typeparam>
+ /// <typeparam name="TFifth"></typeparam>
+ /// <typeparam name="TSixth"></typeparam>
+ /// <typeparam name="TSeventh"></typeparam>
+ /// <typeparam name="TReturn"></typeparam>
+ /// <param name="cnn"></param>
+ /// <param name="sql"></param>
+ /// <param name="map"></param>
+ /// <param name="param"></param>
+ /// <param name="transaction"></param>
+ /// <param name="buffered"></param>
+ /// <param name="splitOn"></param>
+ /// <param name="commandTimeout"></param>
+ /// <param name="commandType"></param>
+ /// <returns></returns>
+ public static async Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
+ {
+ return await MultiMapAsync<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ }
+
+ static async Task<IEnumerable<TReturn>> MultiMapAsync<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType)
+ {
+ var identity = new Identity(sql, commandType, cnn, typeof(TFirst), (object)param == null ? null : ((object)param).GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) });
+ var info = GetCacheInfo(identity);
+ var cmd = (DbCommand)SetupCommand(cnn, transaction, sql, info.ParamReader, param, commandTimeout, commandType);
+ using (var reader = await cmd.ExecuteReaderAsync())
+ {
+ var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, null, map, null, null, splitOn, null, null, reader, identity);
+ return buffered ? results.ToList() : results;
+ }
+ }
+
+ private static IEnumerable<T> ExecuteReader<T>(IDataReader reader, Identity identity, CacheInfo info)
+ {
+ var tuple = info.Deserializer;
+ int hash = GetColumnHash(reader);
+ if (tuple.Func == null || tuple.Hash != hash)
+ {
+ tuple = info.Deserializer = new DeserializerState(hash, GetDeserializer(typeof(T), reader, 0, -1, false));
+ SetQueryCache(identity, info);
+ }
+
+ var func = tuple.Func;
+
+ while (reader.Read())
+ {
+ yield return (T)func(reader);
+ }
+ }
+ }
+}
32 Dapper NET45/dapper-async.nuspec
View
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
+ <metadata schemaVersion="2">
+ <id>Dapper-Async</id>
+ <version>1.03</version>
+ <title>Dapper dot net async</title>
+ <authors>Sam Saffron,Marc Gravell,Brandon Kaid</authors>
+ <owners>Sam Saffron,Marc Gravell,Brandon Kaid</owners>
+ <licenseUrl>http://www.apache.org/licenses/LICENSE-2.0</licenseUrl>
+ <projectUrl>https://github.com/bkaid/dapper-dot-net</projectUrl>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <description>A fork of Dapper with additional QueryAsync methods using .NET Framework 4.5's Task-Based Asynchronous Pattern.</description>
+ <summary>Dapper QueryAsync methods</summary>
+ <tags>Dapper Async Task await</tags>
+ <frameworkAssemblies>
+ <frameworkAssembly assemblyName="System.Core"/>
+ <frameworkAssembly assemblyName="System"/>
+ <frameworkAssembly assemblyName="System.Data"/>
+ <frameworkAssembly assemblyName="Microsoft.CSharp" targetFramework=".NETFramework4.5" />
+ </frameworkAssemblies>
+ <releaseNotes>
+ * 1.03 - Added two more multi-mapper type parameters.
+ * 1.02 - Added async versions of Query methods that do multi-mapping like QueryAsync&lt;TFirst, TSecond, TReturn&gt;
+ * 1.01 - Updated code to use ExecuteReaderAsync on more generic DbCommand instead of SqlCommand.
+ * 1.0 - Initial release.
+ </releaseNotes>
+ </metadata>
+ <files>
+ <file src="bin\Release\Dapper.dll" target="lib\net45" />
+ <file src="bin\Release\Dapper.pdb" target="lib\net45" />
+ </files>
+</package>
114 Dapper/SqlMapper.cs
View
@@ -892,7 +892,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
#endif
)
{
- return MultiMap<TFirst, TSecond, DontMap, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ return MultiMap<TFirst, TSecond, DontMap, DontMap, DontMap, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
}
/// <summary>
@@ -920,7 +920,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
#endif
)
{
- return MultiMap<TFirst, TSecond, TThird, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ return MultiMap<TFirst, TSecond, TThird, DontMap, DontMap, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
}
/// <summary>
@@ -949,9 +949,9 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
#endif
)
{
- return MultiMap<TFirst, TSecond, TThird, TFourth, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ return MultiMap<TFirst, TSecond, TThird, TFourth, DontMap, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
}
-#if !CSHARP30
+
/// <summary>
/// Perform a multi mapping query with 5 input parameters
/// </summary>
@@ -971,23 +971,87 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
/// <param name="commandTimeout"></param>
/// <param name="commandType"></param>
/// <returns></returns>
- public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
+ public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(
+#if CSHARP30
+ this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
+#else
+this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
+#endif
+)
+ {
+ return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ }
+
+ /// <summary>
+ /// Perform a multi mapping query with 6 input parameters
+ /// </summary>
+ /// <typeparam name="TFirst"></typeparam>
+ /// <typeparam name="TSecond"></typeparam>
+ /// <typeparam name="TThird"></typeparam>
+ /// <typeparam name="TFourth"></typeparam>
+ /// <typeparam name="TFifth"></typeparam>
+ /// <typeparam name="TSixth"></typeparam>
+ /// <typeparam name="TReturn"></typeparam>
+ /// <param name="cnn"></param>
+ /// <param name="sql"></param>
+ /// <param name="map"></param>
+ /// <param name="param"></param>
+ /// <param name="transaction"></param>
+ /// <param name="buffered"></param>
+ /// <param name="splitOn"></param>
+ /// <param name="commandTimeout"></param>
+ /// <param name="commandType"></param>
+ /// <returns></returns>
+ public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn>(
+#if CSHARP30
+ this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
+#else
+this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
+#endif
+)
+ {
+ return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ }
+
+#if !CSHARP30
+ /// <summary>
+ /// Perform a multi mapping query with 7 input parameters
+ /// </summary>
+ /// <typeparam name="TFirst"></typeparam>
+ /// <typeparam name="TSecond"></typeparam>
+ /// <typeparam name="TThird"></typeparam>
+ /// <typeparam name="TFourth"></typeparam>
+ /// <typeparam name="TFifth"></typeparam>
+ /// <typeparam name="TSixth"></typeparam>
+ /// <typeparam name="TSeventh"></typeparam>
+ /// <typeparam name="TReturn"></typeparam>
+ /// <param name="cnn"></param>
+ /// <param name="sql"></param>
+ /// <param name="map"></param>
+ /// <param name="param"></param>
+ /// <param name="transaction"></param>
+ /// <param name="buffered"></param>
+ /// <param name="splitOn"></param>
+ /// <param name="commandTimeout"></param>
+ /// <param name="commandType"></param>
+ /// <returns></returns>
+ public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
{
- return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
+ return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
}
#endif
partial class DontMap { }
- static IEnumerable<TReturn> MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(
+ static IEnumerable<TReturn> MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(
this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType)
{
- var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType, null, null);
+ var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType, null, null);
return buffered ? results.ToList() : results;
}
- static IEnumerable<TReturn> MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, string splitOn, int? commandTimeout, CommandType? commandType, IDataReader reader, Identity identity)
+ static IEnumerable<TReturn> MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, string splitOn, int? commandTimeout, CommandType? commandType, IDataReader reader, Identity identity)
{
- identity = identity ?? new Identity(sql, commandType, cnn, typeof(TFirst), (object)param == null ? null : ((object)param).GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth) });
+ identity = identity ?? new Identity(sql, commandType, cnn, typeof(TFirst), (object)param == null ? null : ((object)param).GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) });
CacheInfo cinfo = GetCacheInfo(identity);
IDbCommand ownedCommand = null;
@@ -1007,13 +1071,13 @@ partial class DontMap { }
int hash = GetColumnHash(reader);
if ((deserializer = cinfo.Deserializer).Func == null || (otherDeserializers = cinfo.OtherDeserializers) == null || hash != deserializer.Hash)
{
- var deserializers = GenerateDeserializers(new Type[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth) }, splitOn, reader);
+ var deserializers = GenerateDeserializers(new Type[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) }, splitOn, reader);
deserializer = cinfo.Deserializer = new DeserializerState(hash, deserializers[0]);
otherDeserializers = cinfo.OtherDeserializers = deserializers.Skip(1).ToArray();
SetQueryCache(identity, cinfo);
}
- Func<IDataReader, TReturn> mapIt = GenerateMapper<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(deserializer.Func, otherDeserializers, map);
+ Func<IDataReader, TReturn> mapIt = GenerateMapper<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(deserializer.Func, otherDeserializers, map);
if (mapIt != null)
{
@@ -1042,7 +1106,7 @@ partial class DontMap { }
}
}
- private static Func<IDataReader, TReturn> GenerateMapper<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(Func<IDataReader, object> deserializer, Func<IDataReader, object>[] otherDeserializers, object map)
+ private static Func<IDataReader, TReturn> GenerateMapper<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(Func<IDataReader, object> deserializer, Func<IDataReader, object>[] otherDeserializers, object map)
{
switch(otherDeserializers.Length)
{
@@ -1055,6 +1119,10 @@ partial class DontMap { }
#if !CSHARP30
case 4:
return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r));
+ case 5:
+ return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r));
+ case 6:
+ return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r), (TSeventh)otherDeserializers[5](r));
#endif
default:
throw new NotSupportedException();
@@ -2296,18 +2364,20 @@ public IEnumerable<T> Read<T>()
return ReadDeferred<T>(gridIndex, deserializer.Func, typedIdentity);
}
- private IEnumerable<TReturn> MultiReadInternal<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(object func, string splitOn)
+ private IEnumerable<TReturn> MultiReadInternal<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(object func, string splitOn)
{
var identity = this.identity.ForGrid(typeof(TReturn), new Type[] {
typeof(TFirst),
typeof(TSecond),
typeof(TThird),
typeof(TFourth),
- typeof(TFifth)
+ typeof(TFifth),
+ typeof(TSixth),
+ typeof(TSeventh)
}, gridIndex);
try
{
- foreach (var r in SqlMapper.MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(null, null, func, null, null, splitOn, null, null, reader, identity))
+ foreach (var r in SqlMapper.MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, null, func, null, null, splitOn, null, null, reader, identity))
{
yield return r;
}
@@ -2333,7 +2403,7 @@ public IEnumerable<T> Read<T>()
public IEnumerable<TReturn> Read<TFirst, TSecond, TReturn>(Func<TFirst, TSecond, TReturn> func, string splitOn = "id")
#endif
{
- return MultiReadInternal<TFirst, TSecond, DontMap, DontMap, DontMap, TReturn>(func, splitOn);
+ return MultiReadInternal<TFirst, TSecond, DontMap, DontMap, DontMap, DontMap, DontMap, TReturn>(func, splitOn);
}
/// <summary>
@@ -2352,7 +2422,7 @@ public IEnumerable<T> Read<T>()
public IEnumerable<TReturn> Read<TFirst, TSecond, TThird, TReturn>(Func<TFirst, TSecond, TThird, TReturn> func, string splitOn = "id")
#endif
{
- return MultiReadInternal<TFirst, TSecond, TThird, DontMap, DontMap, TReturn>(func, splitOn);
+ return MultiReadInternal<TFirst, TSecond, TThird, DontMap, DontMap, DontMap, DontMap, TReturn>(func, splitOn);
}
/// <summary>
@@ -2372,7 +2442,7 @@ public IEnumerable<T> Read<T>()
public IEnumerable<TReturn> Read<TFirst, TSecond, TThird, TFourth, TReturn>(Func<TFirst, TSecond, TThird, TFourth, TReturn> func, string splitOn = "id")
#endif
{
- return MultiReadInternal<TFirst, TSecond, TThird, TFourth, DontMap, TReturn>(func, splitOn);
+ return MultiReadInternal<TFirst, TSecond, TThird, TFourth, DontMap, DontMap, DontMap, TReturn>(func, splitOn);
}
#if !CSHARP30
@@ -2384,14 +2454,16 @@ public IEnumerable<T> Read<T>()
/// <typeparam name="TThird"></typeparam>
/// <typeparam name="TFourth"></typeparam>
/// <typeparam name="TFifth"></typeparam>
+ /// <typeparam name="TSixth"></typeparam>
+ /// <typeparam name="TSeventh"></typeparam>
/// <typeparam name="TReturn"></typeparam>
/// <param name="func"></param>
/// <param name="splitOn"></param>
/// <returns></returns>
- public IEnumerable<TReturn> Read<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn> func, string splitOn = "id")
+ public IEnumerable<TReturn> Read<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn> func, string splitOn = "id")
{
- return MultiReadInternal<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(func, splitOn);
+ return MultiReadInternal<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(func, splitOn);
}
#endif
6 DapperTests NET45/App.config
View
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <startup>
+ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+ </startup>
+</configuration>
64 DapperTests NET45/DapperTests NET45.csproj
View
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <ProjectGuid>{B7B69EE5-0E0D-4218-88DF-79E7D2355D26}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>DapperTests_NET45</RootNamespace>
+ <AssemblyName>DapperTests NET45</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;NET45</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE;NET45</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Tests\Assert.cs">
+ <Link>Assert.cs</Link>
+ </Compile>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Tests.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Dapper NET45\Dapper NET45.csproj">
+ <Project>{EDD52209-45E8-42BA-81C1-D39FA1F07646}</Project>
+ <Name>Dapper NET45</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
35 DapperTests NET45/Program.cs
View
@@ -0,0 +1,35 @@
+using System;
+using System.Data.SqlClient;
+using System.Reflection;
+
+namespace DapperTests_NET45
+{
+ class Program
+ {
+ static void Main()
+ {
+ RunTests();
+ Console.WriteLine("(end of tests; press any key)");
+
+ Console.ReadKey();
+ }
+ public static readonly string connectionString = "Data Source=.;Initial Catalog=tempdb;Integrated Security=True";
+
+ public static SqlConnection GetOpenConnection()
+ {
+ var connection = new SqlConnection(connectionString);
+ connection.Open();
+ return connection;
+ }
+ private static void RunTests()
+ {
+ var tester = new Tests();
+ foreach (var method in typeof(Tests).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
+ {
+ Console.Write("Running " + method.Name);
+ method.Invoke(tester, null);
+ Console.WriteLine(" - OK!");
+ }
+ }
+ }
+}
36 DapperTests NET45/Properties/AssemblyInfo.cs
View
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("DapperTests NET45")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("DapperTests NET45")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1f0b3016-b2c8-4ba8-b438-520b784e06a8")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
67 DapperTests NET45/Tests.cs
View
@@ -0,0 +1,67 @@
+using System.Linq;
+using Dapper;
+using SqlMapper;
+
+namespace DapperTests_NET45
+{
+ public class Tests
+ {
+ public void TestBasicStringUsageAsync()
+ {
+ using (var connection = Program.GetOpenConnection())
+ {
+ var query = connection.QueryAsync<string>("select 'abc' as [Value] union all select @txt", new { txt = "def" });
+ var arr = query.Result.ToArray();
+ arr.IsSequenceEqualTo(new[] { "abc", "def" });
+ }
+ }
+
+ public void TestClassWithStringUsageAsync()
+ {
+ using (var connection = Program.GetOpenConnection())
+ {
+ var query = connection.QueryAsync<BasicType>("select 'abc' as [Value] union all select @txt", new { txt = "def" });
+ var arr = query.Result.ToArray();
+ arr.Select(x => x.Value).IsSequenceEqualTo(new[] { "abc", "def" });
+ }
+ }
+
+ public void TestMultiMapWithSplitAsync()
+ {
+ var sql = @"select 1 as id, 'abc' as name, 2 as id, 'def' as name";
+ using (var connection = Program.GetOpenConnection())
+ {
+ var productQuery = connection.QueryAsync<Product, Category, Product>(sql, (prod, cat) =>
+ {
+ prod.Category = cat;
+ return prod;
+ });
+
+ var product = productQuery.Result.First();
+ // assertions
+ product.Id.IsEqualTo(1);
+ product.Name.IsEqualTo("abc");
+ product.Category.Id.IsEqualTo(2);
+ product.Category.Name.IsEqualTo("def");
+ }
+ }
+
+ class Product
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public Category Category { get; set; }
+ }
+ class Category
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public string Description { get; set; }
+ }
+
+ class BasicType
+ {
+ public string Value { get; set; }
+ }
+ }
+}
Something went wrong with that request. Please try again.