Repository: DapperLib/Dapper
Branch: main
Commit: 288730e69b05
Files: 221
Total size: 1.2 MB
Directory structure:
gitextract_2tqsalxj/
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ └── bug_report.md
│ └── workflows/
│ ├── cla.yml
│ └── main.yml
├── .gitignore
├── Build.csproj
├── Dapper/
│ ├── CommandDefinition.cs
│ ├── CommandFlags.cs
│ ├── CompiledRegex.cs
│ ├── CustomPropertyTypeMap.cs
│ ├── Dapper.csproj
│ ├── DataTableHandler.cs
│ ├── DbString.cs
│ ├── DefaultTypeMap.cs
│ ├── DynamicParameters.CachedOutputSetters.cs
│ ├── DynamicParameters.ParamInfo.cs
│ ├── DynamicParameters.cs
│ ├── ExplicitConstructorAttribute.cs
│ ├── Extensions.cs
│ ├── FeatureSupport.cs
│ ├── Global.cs
│ ├── NRT.cs
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── PublicAPI/
│ │ ├── net461/
│ │ │ ├── PublicAPI.Shipped.txt
│ │ │ └── PublicAPI.Unshipped.txt
│ │ ├── net8.0/
│ │ │ ├── PublicAPI.Shipped.txt
│ │ │ └── PublicAPI.Unshipped.txt
│ │ └── netstandard2.0/
│ │ ├── PublicAPI.Shipped.txt
│ │ └── PublicAPI.Unshipped.txt
│ ├── PublicAPI.Shipped.txt
│ ├── PublicAPI.Unshipped.txt
│ ├── SimpleMemberMap.cs
│ ├── SqlDataRecordHandler.cs
│ ├── SqlDataRecordListTVPParameter.cs
│ ├── SqlMapper.Async.cs
│ ├── SqlMapper.CacheInfo.cs
│ ├── SqlMapper.DapperRow.Descriptor.cs
│ ├── SqlMapper.DapperRow.cs
│ ├── SqlMapper.DapperRowMetaObject.cs
│ ├── SqlMapper.DapperTable.cs
│ ├── SqlMapper.DeserializerState.cs
│ ├── SqlMapper.DontMap.cs
│ ├── SqlMapper.GridReader.Async.cs
│ ├── SqlMapper.GridReader.cs
│ ├── SqlMapper.ICustomQueryParameter.cs
│ ├── SqlMapper.IDataReader.cs
│ ├── SqlMapper.IDynamicParameters.cs
│ ├── SqlMapper.IMemberMap.cs
│ ├── SqlMapper.IParameterCallbacks.cs
│ ├── SqlMapper.IParameterLookup.cs
│ ├── SqlMapper.ITypeHandler.cs
│ ├── SqlMapper.ITypeMap.cs
│ ├── SqlMapper.Identity.cs
│ ├── SqlMapper.Link.cs
│ ├── SqlMapper.LiteralToken.cs
│ ├── SqlMapper.Settings.cs
│ ├── SqlMapper.TypeDeserializerCache.cs
│ ├── SqlMapper.TypeHandler.cs
│ ├── SqlMapper.TypeHandlerCache.cs
│ ├── SqlMapper.cs
│ ├── TableValuedParameter.cs
│ ├── TypeExtensions.cs
│ ├── UdtTypeHandler.cs
│ ├── WrappedDataReader.cs
│ ├── WrappedReader.cs
│ └── XmlHandlers.cs
├── Dapper.EntityFramework/
│ ├── Dapper.EntityFramework.csproj
│ ├── DbGeographyHandler.cs
│ ├── DbGeometryHandler.cs
│ ├── Handlers.cs
│ ├── PublicAPI.Shipped.txt
│ └── PublicAPI.Unshipped.txt
├── Dapper.EntityFramework.StrongName/
│ └── Dapper.EntityFramework.StrongName.csproj
├── Dapper.ProviderTools/
│ ├── BulkCopy.cs
│ ├── Dapper.ProviderTools.csproj
│ ├── DbConnectionExtensions.cs
│ ├── DbExceptionExtensions.cs
│ ├── Internal/
│ │ └── DynamicBulkCopy.cs
│ ├── PublicAPI.Shipped.txt
│ └── PublicAPI.Unshipped.txt
├── Dapper.Rainbow/
│ ├── Dapper.Rainbow.csproj
│ ├── Database.Async.cs
│ ├── Database.cs
│ ├── IgnorePropertyAttribute.cs
│ ├── Snapshotter.cs
│ ├── SqlCompactDatabase.cs
│ └── readme.md
├── Dapper.SqlBuilder/
│ ├── Dapper.SqlBuilder.csproj
│ ├── PublicAPI.Shipped.txt
│ ├── PublicAPI.Unshipped.txt
│ ├── Readme.md
│ └── SqlBuilder.cs
├── Dapper.StrongName/
│ └── Dapper.StrongName.csproj
├── Dapper.sln
├── Dapper.sln.DotSettings
├── Dapper.snk
├── Directory.Build.props
├── Directory.Build.targets
├── Directory.Packages.props
├── License.txt
├── NonCLA.md
├── Readme.md
├── appveyor.yml
├── benchmarks/
│ ├── Dapper.Tests.Performance/
│ │ ├── Benchmarks.Belgrade.cs
│ │ ├── Benchmarks.Dapper.cs
│ │ ├── Benchmarks.Dashing.cs
│ │ ├── Benchmarks.EntityFramework.cs
│ │ ├── Benchmarks.EntityFrameworkCore.cs
│ │ ├── Benchmarks.HandCoded.cs
│ │ ├── Benchmarks.Linq2DB.cs
│ │ ├── Benchmarks.Linq2Sql.cs
│ │ ├── Benchmarks.Massive.cs
│ │ ├── Benchmarks.Mighty.cs
│ │ ├── Benchmarks.NHibernate.cs
│ │ ├── Benchmarks.Norm.cs
│ │ ├── Benchmarks.PetaPoco.cs
│ │ ├── Benchmarks.RepoDB.cs
│ │ ├── Benchmarks.ServiceStack.cs
│ │ ├── Benchmarks.SqlMarshal.cs
│ │ ├── Benchmarks.Susanoo.cs
│ │ ├── Benchmarks.XPO.cs
│ │ ├── Benchmarks.cs
│ │ ├── Config.cs
│ │ ├── Dapper.Tests.Performance.csproj
│ │ ├── DapperCacheImpact.cs
│ │ ├── Dashing/
│ │ │ ├── DashingConfiguration.cs
│ │ │ └── Post.cs
│ │ ├── EntityFramework/
│ │ │ └── EFContext.cs
│ │ ├── EntityFrameworkCore/
│ │ │ └── EFCoreContext.cs
│ │ ├── Helpers/
│ │ │ ├── ORMColum.cs
│ │ │ └── ReturnColum.cs
│ │ ├── LegacyTests.cs
│ │ ├── Linq2DB/
│ │ │ ├── ConnectionStringSettings.cs
│ │ │ ├── Linq2DBContext.cs
│ │ │ └── Linq2DbSettings.cs
│ │ ├── Linq2Sql/
│ │ │ ├── DataClasses.dbml
│ │ │ ├── DataClasses.dbml.layout
│ │ │ └── DataClasses.designer.cs
│ │ ├── Massive/
│ │ │ └── Massive.cs
│ │ ├── NHibernate/
│ │ │ ├── NHibernateHelper.cs
│ │ │ ├── Post.hbm.xml
│ │ │ └── hibernate.cfg.xml
│ │ ├── PetaPoco/
│ │ │ └── PetaPoco.cs
│ │ ├── Post.cs
│ │ ├── Program.cs
│ │ ├── SqlDataReaderHelper.cs
│ │ ├── XPO/
│ │ │ └── Post.cs
│ │ └── app.config
│ └── Directory.Build.props
├── build.cmd
├── build.ps1
├── docs/
│ ├── _config.yml
│ ├── dapperplus.md
│ ├── docs.csproj
│ ├── index.md
│ └── readme.md
├── global.json
├── nuget.config
├── signatures/
│ └── version1/
│ └── cla.json
├── tests/
│ ├── Dapper.Tests/
│ │ ├── App.config
│ │ ├── AsyncTests.cs
│ │ ├── ConstructorTests.cs
│ │ ├── Dapper.Tests.csproj
│ │ ├── DataReaderTests.cs
│ │ ├── DateTimeOnlyTests.cs
│ │ ├── DecimalTests.cs
│ │ ├── EnumTests.cs
│ │ ├── Helpers/
│ │ │ ├── Attributes.cs
│ │ │ ├── Common.cs
│ │ │ ├── IsExternalInit.cs
│ │ │ ├── SqlServerTypesLoader.cs
│ │ │ ├── TransactedConnection.cs
│ │ │ └── XunitSkippable.cs
│ │ ├── LiteralTests.cs
│ │ ├── MiscTests.cs
│ │ ├── MultiMapTests.cs
│ │ ├── NullTests.cs
│ │ ├── ParameterTests.cs
│ │ ├── ProcedureTests.cs
│ │ ├── ProviderTests.cs
│ │ ├── Providers/
│ │ │ ├── DuckDBTests.cs
│ │ │ ├── EntityFrameworkTests.cs
│ │ │ ├── FirebirdTests.cs
│ │ │ ├── Linq2SqlTests.cs
│ │ │ ├── MySQLTests.cs
│ │ │ ├── OLDEBTests.cs
│ │ │ ├── PostgresqlTests.cs
│ │ │ ├── SnowflakeTests.cs
│ │ │ └── SqliteTests.cs
│ │ ├── QueryMultipleTests.cs
│ │ ├── SharedTypes/
│ │ │ ├── Address.cs
│ │ │ ├── Bar1.cs
│ │ │ ├── Category.cs
│ │ │ ├── Comment.cs
│ │ │ ├── Dog.cs
│ │ │ ├── Enums.cs
│ │ │ ├── Foo1.cs
│ │ │ ├── HazNameId.cs
│ │ │ ├── Index.cs
│ │ │ ├── Person.cs
│ │ │ ├── Post.cs
│ │ │ ├── Product.cs
│ │ │ ├── ReviewBoard.cs
│ │ │ ├── ShortEnum.cs
│ │ │ ├── SomeType.cs
│ │ │ └── User.cs
│ │ ├── SingleRowTests.cs
│ │ ├── SqlBuilderTests.cs
│ │ ├── TestBase.cs
│ │ ├── TransactionTests.cs
│ │ ├── TupleTests.cs
│ │ ├── TypeHandlerTests.cs
│ │ ├── WrappedReaderTests.cs
│ │ ├── XmlTests.cs
│ │ └── xunit.runner.json
│ ├── Directory.Build.props
│ ├── Directory.Build.targets
│ └── docker-compose.yml
└── version.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# EditorConfig is awesome:http://EditorConfig.org
# top-most EditorConfig file
root = true
# Don't use tabs for indentation.
[*]
indent_style = space
# (Please don't specify an indent_size here; that has too many unintended consequences.)
# Code files
[*.{cs,csx,vb,vbx}]
indent_size = 4
insert_final_newline = true
charset = utf-8-bom
# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 2
# Xml config files
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
indent_size = 2
# JSON files
[*.json]
indent_size = 2
# Dotnet code style settings:
[*.{cs,vb}]
# Sort using and Import directives with System.* appearing first
dotnet_sort_system_directives_first = true
# Avoid "this." and "Me." if not necessary
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Use language keywords instead of framework type names for type references
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Suggest more modern language features when available
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
# CSharp code style settings:
[*.cs]
# Prefer "var" everywhere
#csharp_style_var_for_built_in_types = true:suggestion
#csharp_style_var_when_type_is_apparent = false:suggestion
#csharp_style_var_elsewhere = true:suggestion
# Prefer method-like constructs to have a expression-body
csharp_style_expression_bodied_methods = true:none
csharp_style_expression_bodied_constructors = true:none
csharp_style_expression_bodied_operators = true:none
# Prefer property-like constructs to have an expression-body
csharp_style_expression_bodied_properties = true:none
csharp_style_expression_bodied_indexers = true:none
csharp_style_expression_bodied_accessors = true:none
# Suggest more modern language features when available
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Newline settings
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
================================================
FILE: .gitattributes
================================================
* text=auto
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
*.jpg binary
*.png binary
*.gif binary
*.cs -text diff=csharp
*.vb -text
*.c -text
*.cpp -text
*.cxx -text
*.h -text
*.hxx -text
*.py -text
*.rb -text
*.java -text
*.html -text
*.htm -text
*.css -text
*.scss -text
*.sass -text
*.less -text
*.js -text
*.lisp -text
*.clj -text
*.sql -text
*.php -text
*.lua -text
*.m -text
*.asm -text
*.erl -text
*.fs -text
*.fsx -text
*.hs -text
*.csproj -text merge=union
*.vbproj -text merge=union
*.fsproj -text merge=union
*.dbproj -text merge=union
*.sln -text merge=union
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: [mgravell, dapperlib]
custom: ["https://www.buymeacoffee.com/marcgravell"]
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug, needs-triage
assignees: ''
---
**Check your library version, and try updating**
To help, we're going to need to know your library version. If it isn't the latest: *go do that* - it might
fix the problem, and even if it doesn't: you're going to need to update if we find a problem and fix it,
so you might as well get ready for that now.
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected and actual behavior**
A clear and concise description of what you expected to happen, and what actually happens.
**Additional context**
Add any other context about the problem here:
- what DB backend (and version) are you using, if relevant?
- what ADO.NET provider (and version) are you using, if relevant?
- what OS and .NET runtime (and version) are you using, if relevant?
================================================
FILE: .github/workflows/cla.yml
================================================
name: "CLA Assistant"
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened,closed,synchronize]
# explicitly configure permissions, in case your GITHUB_TOKEN workflow permissions are set to read-only in repository settings
permissions:
actions: write
contents: write
pull-requests: write
statuses: write
jobs:
CLAAssistant:
runs-on: ubuntu-latest
steps:
- name: "CLA Assistant"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
uses: contributor-assistant/github-action@v2.3.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# the below token should have repo scope and must be manually added by you in the repository's secret
# This token is required only if you have configured to store the signatures in a remote repository/organization
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
with:
path-to-signatures: 'signatures/version1/cla.json'
path-to-document: 'https://raw.githubusercontent.com/DapperLib/Dapper/main/NonCLA.md' # e.g. a CLA or a DCO document
# branch should not be protected
branch: 'main'
# allowlist: user1,bot*
# the followings are the optional inputs - If the optional inputs are not given, then default values will be taken
#remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository)
#remote-repository-name: enter the remote repository name where the signatures should be stored (Default is storing the signatures in the same repository)
#create-file-commit-message: 'For example: Creating file for storing CLA Signatures'
#signed-commit-message: 'For example: $contributorName has signed the CLA in $owner/$repo#$pullRequestNo'
#custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign'
#custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA'
#custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.'
#lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true)
#use-dco-flag: true - If you are using DCO instead of CLA
================================================
FILE: .github/workflows/main.yml
================================================
name: Main Build
on:
pull_request:
push:
branches:
- main
paths:
- '*'
- '!/docs/*' # Don't run workflow when files are only in the /docs directory
jobs:
vm-job:
name: Ubuntu
runs-on: ubuntu-latest
services:
postgres:
image: postgres
ports:
- 5432/tcp
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
sqlserver:
image: mcr.microsoft.com/mssql/server:2019-latest
ports:
- 1433/tcp
env:
ACCEPT_EULA: Y
SA_PASSWORD: "Password."
mysql:
image: mysql
ports:
- 3306/tcp
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test
steps:
- name: Checkout code
uses: actions/checkout@v1
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: .NET Build
run: dotnet build Build.csproj -c Release /p:CI=true
- name: Dapper Tests
run: dotnet test tests/Dapper.Tests/Dapper.Tests.csproj -c Release --logger GitHubActions -p:CI=true -p:TestTfmsInParallel=false
env:
MySqlConnectionString: Server=localhost;Port=${{ job.services.mysql.ports[3306] }};Uid=root;Pwd=root;Database=test;Allow User Variables=true
OLEDBConnectionString: Provider=SQLOLEDB;Server=tcp:localhost,${{ job.services.sqlserver.ports[1433] }};Database=tempdb;User Id=sa;Password=Password.;
PostgesConnectionString: Server=localhost;Port=${{ job.services.postgres.ports[5432] }};Database=test;User Id=postgres;Password=postgres;
SqlServerConnectionString: Server=tcp:localhost,${{ job.services.sqlserver.ports[1433] }};Database=tempdb;User Id=sa;Password=Password.;
- name: .NET Lib Pack
run: dotnet pack Build.csproj --no-build -c Release /p:PackageOutputPath=%CD%\.nupkgs /p:CI=true
================================================
FILE: .gitignore
================================================
/*.suo
.vs/
.vscode/
bin/
obj/
/*.user
_Resharper*
.hgtags
NuGet.exe
*.user
*.nupkg
.nupkgs/
.docstats
*.ide/
*.lock.json
*.coverage
Test.DB.*
TestResults/
Dapper.Tests/*.sdf
Dapper.Tests/SqlServerTypes/
.dotnet/*
BenchmarkDotNet.Artifacts/
.idea/
.DS_Store
================================================
FILE: Build.csproj
================================================
================================================
FILE: Dapper/CommandDefinition.cs
================================================
using System;
using System.Data;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
namespace Dapper
{
///
/// Represents the key aspects of a sql operation
///
public readonly struct CommandDefinition
{
internal static CommandDefinition ForCallback(object? parameters, CommandFlags flags)
{
return new CommandDefinition(parameters is DynamicParameters ? parameters : null, flags);
}
internal void OnCompleted()
{
(Parameters as SqlMapper.IParameterCallbacks)?.OnCompleted();
}
///
/// The command (sql or a stored-procedure name) to execute
///
public string CommandText { get; }
///
/// The parameters associated with the command
///
public object? Parameters { get; }
///
/// The active transaction for the command
///
public IDbTransaction? Transaction { get; }
///
/// The effective timeout for the command
///
public int? CommandTimeout { get; }
internal readonly CommandType CommandTypeDirect;
///
/// The type of command that the command-text represents
///
#if DEBUG // prevent use in our own code
[Obsolete("Prefer " + nameof(CommandTypeDirect), true)]
#endif
public CommandType? CommandType => CommandTypeDirect;
///
/// Should data be buffered before returning?
///
public bool Buffered => (Flags & CommandFlags.Buffered) != 0;
///
/// Should the plan for this query be cached?
///
internal bool AddToCache => (Flags & CommandFlags.NoCache) == 0;
///
/// Additional state flags against this command
///
public CommandFlags Flags { get; }
///
/// Can async queries be pipelined?
///
public bool Pipelined => (Flags & CommandFlags.Pipelined) != 0;
///
/// Initialize the command definition
///
/// The text for this command.
/// The parameters for this command.
/// The transaction for this command to participate in.
/// The timeout (in seconds) for this command.
/// The for this command.
/// The behavior flags for this command.
/// The cancellation token for this command.
public CommandDefinition(string commandText, object? parameters = null, IDbTransaction? transaction = null, int? commandTimeout = null,
CommandType? commandType = null, CommandFlags flags = CommandFlags.Buffered
, CancellationToken cancellationToken = default
)
{
CommandText = commandText;
Parameters = parameters;
Transaction = transaction;
CommandTimeout = commandTimeout;
CommandTypeDirect = commandType ?? InferCommandType(commandText);
Flags = flags;
CancellationToken = cancellationToken;
}
internal static CommandType InferCommandType(string sql)
{
// if the sql contains any whitespace character (space/tab/cr/lf/etc - via unicode),
// has operators, comments, semi-colon, or a known exception: interpret as ad-hoc;
// otherwise, simple names like "SomeName" should be treated as a stored-proc
// (note TableDirect would need to be specified explicitly, but in reality providers don't usually support TableDirect anyway)
if (sql is null || CompiledRegex.WhitespaceOrReserved.IsMatch(sql)) return System.Data.CommandType.Text;
return System.Data.CommandType.StoredProcedure;
}
private CommandDefinition(object? parameters, CommandFlags flags) : this()
{
Parameters = parameters;
Flags = flags;
CommandText = "";
}
///
/// For asynchronous operations, the cancellation-token
///
public CancellationToken CancellationToken { get; }
internal IDbCommand SetupCommand(IDbConnection cnn, Action? paramReader)
{
var cmd = cnn.CreateCommand();
var init = GetInit(cmd.GetType());
init?.Invoke(cmd);
if (Transaction is not null)
cmd.Transaction = Transaction;
cmd.CommandText = CommandText;
if (CommandTimeout.HasValue)
{
cmd.CommandTimeout = CommandTimeout.Value;
}
else if (SqlMapper.Settings.CommandTimeout.HasValue)
{
cmd.CommandTimeout = SqlMapper.Settings.CommandTimeout.Value;
}
cmd.CommandType = CommandTypeDirect;
paramReader?.Invoke(cmd, Parameters);
return cmd;
}
private static SqlMapper.Link>? commandInitCache;
internal static void ResetCommandInitCache()
=> SqlMapper.Link>.Clear(ref commandInitCache);
private static Action? GetInit(Type commandType)
{
if (commandType is null)
return null; // GIGO
if (SqlMapper.Link>.TryGet(commandInitCache, commandType, out Action? action))
{
return action;
}
var bindByName = GetBasicPropertySetter(commandType, "BindByName", typeof(bool));
var initialLongFetchSize = GetBasicPropertySetter(commandType, "InitialLONGFetchSize", typeof(int));
var fetchSize = GetBasicPropertySetter(commandType, "FetchSize", typeof(long));
action = null;
if (bindByName is not null || initialLongFetchSize is not null || fetchSize is not null)
{
var method = new DynamicMethod(commandType.Name + "_init", null, new Type[] { typeof(IDbCommand) });
var il = method.GetILGenerator();
if (bindByName is not null)
{
// .BindByName = true
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, commandType);
il.Emit(OpCodes.Ldc_I4_1);
il.EmitCall(OpCodes.Callvirt, bindByName, null);
}
if (initialLongFetchSize is not null)
{
// .InitialLONGFetchSize = -1
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, commandType);
il.Emit(OpCodes.Ldc_I4_M1);
il.EmitCall(OpCodes.Callvirt, initialLongFetchSize, null);
}
if (fetchSize is not null)
{
var snapshot = SqlMapper.Settings.FetchSize;
if (snapshot >= 0)
{
// .FetchSize = {withValue}
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Castclass, commandType);
il.Emit(OpCodes.Ldc_I8, snapshot); // bake it as a constant
il.EmitCall(OpCodes.Callvirt, fetchSize, null);
}
}
il.Emit(OpCodes.Ret);
action = (Action)method.CreateDelegate(typeof(Action));
}
// cache it
SqlMapper.Link>.TryAdd(ref commandInitCache, commandType, ref action!);
return action;
}
private static MethodInfo? GetBasicPropertySetter(Type declaringType, string name, Type expectedType)
{
var prop = declaringType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance);
if (prop?.CanWrite == true && prop.PropertyType == expectedType && prop.GetIndexParameters().Length == 0)
{
return prop.GetSetMethod();
}
return null;
}
}
}
================================================
FILE: Dapper/CommandFlags.cs
================================================
using System;
namespace Dapper
{
///
/// Additional state flags that control command behaviour
///
[Flags]
public enum CommandFlags
{
///
/// No additional flags
///
None = 0,
///
/// Should data be buffered before returning?
///
Buffered = 1,
///
/// Can async queries be pipelined?
///
Pipelined = 2,
///
/// Should the plan cache be bypassed?
///
NoCache = 4,
}
}
================================================
FILE: Dapper/CompiledRegex.cs
================================================
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
namespace Dapper;
internal static partial class CompiledRegex
{
#if DEBUG && NET7_0_OR_GREATER // enables colorization in IDE
[StringSyntax("Regex")]
#endif
private const string
WhitespaceOrReservedPattern = @"[\s;/\-+*]|^vacuum$|^commit$|^rollback$|^revert$",
LegacyParameterPattern = @"(? LegacyParameterGen();
internal static Regex LiteralTokens => LiteralTokensGen();
internal static Regex PseudoPositional => PseudoPositionalGen();
internal static Regex WhitespaceOrReserved => WhitespaceOrReservedGen();
#else
internal static Regex LegacyParameter { get; }
= new(LegacyParameterPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant | RegexOptions.Compiled);
internal static Regex LiteralTokens { get; }
= new(LiteralTokensPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant | RegexOptions.Compiled);
internal static Regex PseudoPositional { get; }
= new(PseudoPositionalPattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
internal static Regex WhitespaceOrReserved { get; }
= new(WhitespaceOrReservedPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
#endif
}
================================================
FILE: Dapper/CustomPropertyTypeMap.cs
================================================
using System;
using System.Reflection;
namespace Dapper
{
///
/// Implements custom property mapping by user provided criteria (usually presence of some custom attribute with column to member mapping)
///
public sealed class CustomPropertyTypeMap : SqlMapper.ITypeMap
{
private readonly Type _type;
private readonly Func _propertySelector;
///
/// Creates custom property mapping
///
/// Target entity type
/// Property selector based on target type and DataReader column name
public CustomPropertyTypeMap(Type type, Func propertySelector)
{
_type = type ?? throw new ArgumentNullException(nameof(type));
_propertySelector = propertySelector ?? throw new ArgumentNullException(nameof(propertySelector));
}
///
/// Always returns default constructor
///
/// DataReader column names
/// DataReader column types
/// Default constructor
public ConstructorInfo? FindConstructor(string[] names, Type[] types) =>
_type.GetConstructor(Array.Empty())!;
///
/// Always returns null
///
///
public ConstructorInfo? FindExplicitConstructor() => null;
///
/// Not implemented as far as default constructor used for all cases
///
///
///
///
public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName)
{
throw new NotSupportedException();
}
///
/// Returns property based on selector strategy
///
/// DataReader column name
/// Property member map
public SqlMapper.IMemberMap? GetMember(string columnName)
{
var prop = _propertySelector(_type, columnName);
return prop is not null ? new SimpleMemberMap(columnName, prop) : null;
}
}
}
================================================
FILE: Dapper/Dapper.csproj
================================================
Dapper
Dapper
orm;sql;micro-orm
A high performance Micro-ORM supporting SQL Server, MySQL, Sqlite, SqlCE, Firebird etc. Major Sponsor: Dapper Plus from ZZZ Projects.
Sam Saffron;Marc Gravell;Nick Craver
net461;netstandard2.0;net8.0;net10.0
enable
true
all
runtime; build; native; contentfiles; analyzers
================================================
FILE: Dapper/DataTableHandler.cs
================================================
using System;
using System.Data;
namespace Dapper
{
internal sealed class DataTableHandler : SqlMapper.ITypeHandler
{
public object Parse(Type destinationType, object value)
{
throw new NotImplementedException();
}
public void SetValue(IDbDataParameter parameter, object value)
{
TableValuedParameter.Set(parameter, value as DataTable, null);
}
}
}
================================================
FILE: Dapper/DbString.cs
================================================
using System;
using System.Data;
namespace Dapper
{
///
/// This class represents a SQL string, it can be used if you need to denote your parameter is a Char vs VarChar vs nVarChar vs nChar
///
public sealed class DbString : SqlMapper.ICustomQueryParameter
{
///
/// Default value for IsAnsi.
///
public static bool IsAnsiDefault { get; set; }
///
/// A value to set the default value of strings
/// going through Dapper. Default is 4000, any value larger than this
/// field will not have the default value applied.
///
public const int DefaultLength = 4000;
///
/// Create a new DbString
///
public DbString()
{
Length = -1;
IsAnsi = IsAnsiDefault;
}
///
/// Create a new DbString
///
public DbString(string? value, int length = -1)
{
Value = value;
Length = length;
IsAnsi = IsAnsiDefault;
}
///
/// Ansi vs Unicode
///
public bool IsAnsi { get; set; }
///
/// Fixed length
///
public bool IsFixedLength { get; set; }
///
/// Length of the string -1 for max
///
public int Length { get; set; }
///
/// The value of the string
///
public string? Value { get; set; }
///
/// Gets a string representation of this DbString.
///
public override string ToString() => Value is null
? $"Dapper.DbString (Value: null, Length: {Length}, IsAnsi: {IsAnsi}, IsFixedLength: {IsFixedLength})"
: $"Dapper.DbString (Value: '{Value}', Length: {Length}, IsAnsi: {IsAnsi}, IsFixedLength: {IsFixedLength})";
///
/// Add the parameter to the command... internal use only
///
///
///
public void AddParameter(IDbCommand command, string name)
{
if (IsFixedLength && Length == -1)
{
throw new InvalidOperationException("If specifying IsFixedLength, a Length must also be specified");
}
bool add = !command.Parameters.Contains(name);
IDbDataParameter param;
if (add)
{
param = command.CreateParameter();
param.ParameterName = name;
}
else
{
param = (IDbDataParameter)command.Parameters[name];
}
#pragma warning disable 0618
param.Value = SqlMapper.SanitizeParameterValue(Value);
#pragma warning restore 0618
if (Length == -1 && Value is not null && Value.Length <= DefaultLength)
{
param.Size = DefaultLength;
}
else
{
param.Size = Length;
}
param.DbType = IsAnsi ? (IsFixedLength ? DbType.AnsiStringFixedLength : DbType.AnsiString) : (IsFixedLength ? DbType.StringFixedLength : DbType.String);
if (add)
{
command.Parameters.Add(param);
}
}
}
}
================================================
FILE: Dapper/DefaultTypeMap.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Dapper
{
///
/// Represents default type mapping strategy used by Dapper
///
public sealed class DefaultTypeMap : SqlMapper.ITypeMap
{
private readonly List _fields;
private readonly Type _type;
///
/// Creates default type map
///
/// Entity type
public DefaultTypeMap(Type type)
{
if (type is null)
throw new ArgumentNullException(nameof(type));
_fields = GetSettableFields(type);
Properties = GetSettableProps(type);
_type = type;
}
internal static MethodInfo GetPropertySetterOrThrow(PropertyInfo propertyInfo, Type type)
{
return GetPropertySetter(propertyInfo, type) ?? Throw(propertyInfo);
static MethodInfo Throw(PropertyInfo propertyInfo) => throw new InvalidOperationException("Property setting not found for: " + propertyInfo?.Name);
}
internal static MethodInfo? GetPropertySetter(PropertyInfo propertyInfo, Type type)
{
if (propertyInfo.DeclaringType == type) return propertyInfo.GetSetMethod(true);
return propertyInfo.DeclaringType!.GetProperty(
propertyInfo.Name,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
Type.DefaultBinder,
propertyInfo.PropertyType,
propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray(),
null)!.GetSetMethod(true);
}
internal static List GetSettableProps(Type t)
{
return t
.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Where(p => GetPropertySetter(p, t) is not null)
.ToList();
}
internal static List GetSettableFields(Type t)
{
return t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).ToList();
}
///
/// Finds best constructor
///
/// DataReader column names
/// DataReader column types
/// Matching constructor or default one
public ConstructorInfo? FindConstructor(string[] names, Type[] types)
{
var constructors = _type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (ConstructorInfo ctor in constructors.OrderBy(c => c.IsPublic ? 0 : (c.IsPrivate ? 2 : 1)).ThenBy(c => c.GetParameters().Length))
{
ParameterInfo[] ctorParameters = ctor.GetParameters();
if (ctorParameters.Length == 0)
return ctor;
if (ctorParameters.Length != types.Length)
continue;
int i = 0;
for (; i < ctorParameters.Length; i++)
{
if (EqualsCI(ctorParameters[i].Name, names[i]))
{ } // exact match
else if (MatchNamesWithUnderscores && EqualsCIU(ctorParameters[i].Name, names[i]))
{ } // match after applying underscores
else
{
// not a name match
break;
}
if (types[i] == typeof(byte[]) && ctorParameters[i].ParameterType.FullName == SqlMapper.LinqBinary)
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 == typeof(char) && types[i] == typeof(string))
&& !(unboxedType.IsEnum && types[i] == typeof(string)))
{
break;
}
}
if (i == ctorParameters.Length)
return ctor;
}
return null;
}
///
/// Returns the constructor, if any, that has the ExplicitConstructorAttribute on it.
///
public ConstructorInfo? FindExplicitConstructor()
{
var constructors = _type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var withAttr = constructors.Where(c => c.GetCustomAttributes(typeof(ExplicitConstructorAttribute), true).Length > 0).ToList();
if (withAttr.Count == 1)
{
return withAttr[0];
}
return null;
}
///
/// Gets mapping for constructor parameter
///
/// Constructor to resolve
/// DataReader column name
/// Mapping implementation
public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName)
{
var param = MatchFirstOrDefault(constructor.GetParameters(), columnName, static p => p.Name) ?? Throw(columnName);
return new SimpleMemberMap(columnName, param);
static ParameterInfo Throw(string name) => throw new ArgumentException("Constructor parameter not found for " + name);
}
///
/// Gets member mapping for column
///
/// DataReader column name
/// Mapping implementation
public SqlMapper.IMemberMap? GetMember(string columnName)
{
var property = MatchFirstOrDefault(Properties, columnName, static p => p.Name);
if (property is not null)
return new SimpleMemberMap(columnName, property);
// roslyn automatically implemented properties, in particular for get-only properties: <{Name}>k__BackingField;
var backingFieldName = "<" + columnName + ">k__BackingField";
// preference order is:
// exact match over underscore match, exact case over wrong case, backing fields over regular fields, match-inc-underscores over match-exc-underscores
var field = _fields.Find(p => string.Equals(p.Name, columnName, StringComparison.Ordinal))
?? _fields.Find(p => string.Equals(p.Name, backingFieldName, StringComparison.Ordinal))
?? _fields.Find(p => string.Equals(p.Name, columnName, StringComparison.OrdinalIgnoreCase))
?? _fields.Find(p => string.Equals(p.Name, backingFieldName, StringComparison.OrdinalIgnoreCase));
if (field is null && MatchNamesWithUnderscores)
{
var effectiveColumnName = columnName.Replace("_", "");
backingFieldName = "<" + effectiveColumnName + ">k__BackingField";
field = _fields.Find(p => string.Equals(p.Name, effectiveColumnName, StringComparison.Ordinal))
?? _fields.Find(p => string.Equals(p.Name, backingFieldName, StringComparison.Ordinal))
?? _fields.Find(p => string.Equals(p.Name, effectiveColumnName, StringComparison.OrdinalIgnoreCase))
?? _fields.Find(p => string.Equals(p.Name, backingFieldName, StringComparison.OrdinalIgnoreCase));
}
if (field is not null)
return new SimpleMemberMap(columnName, field);
return null;
}
///
/// Should column names like User_Id be allowed to match properties/fields like UserId ?
///
public static bool MatchNamesWithUnderscores { get; set; }
static T? MatchFirstOrDefault(IList? members, string? name, Func selector) where T : class
{
if (members is { Count: > 0 })
{
// try exact first
foreach (var member in members)
{
if (string.Equals(name, selector(member), StringComparison.Ordinal))
{
return member;
}
}
// then exact ignoring case
foreach (var member in members)
{
if (string.Equals(name, selector(member), StringComparison.OrdinalIgnoreCase))
{
return member;
}
}
if (MatchNamesWithUnderscores)
{
// same again, minus underscore delta
name = name?.Replace("_", "");
// match normalized column name vs actual property name
foreach (var member in members)
{
if (string.Equals(name, selector(member), StringComparison.Ordinal))
{
return member;
}
}
foreach (var member in members)
{
if (string.Equals(name, selector(member), StringComparison.OrdinalIgnoreCase))
{
return member;
}
}
// match normalized column name vs normalized property name
foreach (var member in members)
{
if (string.Equals(name, selector(member)?.Replace("_", ""), StringComparison.Ordinal))
{
return member;
}
}
foreach (var member in members)
{
if (string.Equals(name, selector(member)?.Replace("_", ""), StringComparison.OrdinalIgnoreCase))
{
return member;
}
}
}
}
return null;
}
internal static bool EqualsCI(string? x, string? y)
=> string.Equals(x, y, StringComparison.OrdinalIgnoreCase);
internal static bool EqualsCIU(string? x, string? y)
=> string.Equals(x?.Replace("_", ""), y?.Replace("_", ""), StringComparison.OrdinalIgnoreCase);
///
/// The settable properties for this typemap
///
public List Properties { get; }
}
}
================================================
FILE: Dapper/DynamicParameters.CachedOutputSetters.cs
================================================
using System.Collections;
namespace Dapper
{
public partial class DynamicParameters
{
// The type here is used to differentiate the cache by type via generics
// ReSharper disable once UnusedTypeParameter
internal static class CachedOutputSetters
{
// Intentional, abusing generics to get our cache splits
// ReSharper disable once StaticMemberInGenericType
public static readonly Hashtable Cache = new Hashtable();
}
}
}
================================================
FILE: Dapper/DynamicParameters.ParamInfo.cs
================================================
using System;
using System.Data;
namespace Dapper
{
public partial class DynamicParameters
{
private sealed class ParamInfo
{
public string Name { get; set; } = null!;
public object? Value { get; set; }
public ParameterDirection ParameterDirection { get; set; }
public DbType? DbType { get; set; }
public int? Size { get; set; }
public IDbDataParameter AttachedParam { get; set; } = null!;
internal Action