Skip to content
Sign up Sign in
This repository
Explore
Features
Enterprise
Blog
Watch Star , Fork StackExchange/dapper-dot-net
branch: master dapper-dot-net/Tests/Tests.cs
@mgravellmgravell days ago SO30435185; make it clearer if the caller is passing an array (etc) w…
contributors @mgravell @invalid-email-address @vosen @SamSaffron @jamesholwell @azhmur @jkonecki @brannon @teamyudin @markjerz @simonkang @kevin-montrose @johnleegrant @mrange @tms @fbdegroot @tuespetre @greygeek @RichCzyzewski @matwilko @xps
RawBlameHistory lines ( sloc) 178.799 kb
//#define POSTGRESQL // uncomment to run postgres tests #if DNXCORE50
using IDbCommand = global::System.Data.Common.DbCommand;
using IDbDataParameter = global::System.Data.Common.DbParameter;
using IDbConnection = global::System.Data.Common.DbConnection;
using IDbTransaction = global::System.Data.Common.DbTransaction;
using IDataReader = global::System.Data.Common.DbDataReader;
#endif using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using Dapper;
using System.IO;
using System.Data;
using System.Collections;
using System.Reflection;
using System.Dynamic;
using System.ComponentModel;
using Microsoft.CSharp.RuntimeBinder;
using System.Data.Common;
using System.Globalization;
using System.Threading;
using System.Data.SqlTypes;
using System.Diagnostics; #if EXTERNALS
using FirebirdSql.Data.FirebirdClient;
using System.Data.Entity.Spatial;
using Microsoft.SqlServer.Types;
using System.Data.SqlServerCe;
#if POSTGRESQL
using Npgsql;
#endif
#endif #if DNXCORE50
namespace System.ComponentModel {
public sealed class DescriptionAttribute : Attribute {
public DescriptionAttribute(string description)
{
Description = description;
}
public string Description {get;private set;}
}
}
namespace System
{
public enum GenericUriParserOptions
{
Default
}
public class GenericUriParser
{
private GenericUriParserOptions options; public GenericUriParser(GenericUriParserOptions options)
{
this.options = options;
}
}
}
#endif namespace SqlMapper
{ class Tests
{
SqlConnection connection = Program.GetOpenConnection(); public class AbstractInheritance
{
public abstract class Order
{
internal int Internal { get; set; }
protected int Protected { get; set; }
public int Public { get; set; } public int ProtectedVal { get { return Protected; } }
} public class ConcreteOrder : Order
{
public int Concrete { get; set; }
}
} class UserWithConstructor
{
public UserWithConstructor(int id, string name)
{
Ident = id;
FullName = name;
}
public int Ident { get; set; }
public string FullName { get; set; }
} class PostWithConstructor
{
public PostWithConstructor(int id, int ownerid, string content)
{
Ident = id;
FullContent = content;
} public int Ident { get; set; }
public UserWithConstructor Owner { get; set; }
public string FullContent { get; set; }
public Comment Comment { get; set; }
} public void TestMultiMapWithConstructor()
{
var createSql = @"
create table #Users (Id int, Name varchar(20))
create table #Posts (Id int, OwnerId int, Content varchar(20))
insert #Users values(99, 'Sam')
insert #Users values(2, 'I am')
insert #Posts values(1, 99, 'Sams Post1')
insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')";
connection.Execute(createSql);
try
{
string sql = @"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id";
PostWithConstructor[] data = connection.Query<PostWithConstructor, UserWithConstructor, PostWithConstructor>(sql, (post, user) => { post.Owner = user; return post; }).ToArray();
var p = data.First(); p.FullContent.IsEqualTo("Sams Post1");
p.Ident.IsEqualTo();
p.Owner.FullName.IsEqualTo("Sam");
p.Owner.Ident.IsEqualTo(); data[].Owner.IsNull();
}
finally
{
connection.Execute("drop table #Users drop table #Posts");
}
} class MultipleConstructors
{
public MultipleConstructors()
{ }
public MultipleConstructors(int a, string b)
{
A = a + ;
B = b + "!";
}
public int A { get; set; }
public string B { get; set; }
} public void TestMultipleConstructors()
{
MultipleConstructors mult = connection.Query<MultipleConstructors>("select 0 A, 'Dapper' b").First();
mult.A.IsEqualTo();
mult.B.IsEqualTo("Dapper");
} class ConstructorsWithAccessModifiers
{
private ConstructorsWithAccessModifiers()
{
}
public ConstructorsWithAccessModifiers(int a, string b)
{
A = a + ;
B = b + "!";
}
public int A { get; set; }
public string B { get; set; }
} public void TestConstructorsWithAccessModifiers()
{
ConstructorsWithAccessModifiers value = connection.Query<ConstructorsWithAccessModifiers>("select 0 A, 'Dapper' b").First();
value.A.IsEqualTo();
value.B.IsEqualTo("Dapper!");
} class NoDefaultConstructor
{
public NoDefaultConstructor(int a1, int? b1, float f1, string s1, Guid G1)
{
A = a1;
B = b1;
F = f1;
S = s1;
G = G1;
}
public int A { get; set; }
public int? B { get; set; }
public float F { get; set; }
public string S { get; set; }
public Guid G { get; set; }
} public void TestNoDefaultConstructor()
{
var guid = Guid.NewGuid();
NoDefaultConstructor nodef = connection.Query<NoDefaultConstructor>("select CAST(NULL AS integer) A1, CAST(NULL AS integer) b1, CAST(NULL AS real) f1, 'Dapper' s1, G1 = @id", new { id = guid }).First();
nodef.A.IsEqualTo();
nodef.B.IsEqualTo(null);
nodef.F.IsEqualTo();
nodef.S.IsEqualTo("Dapper");
nodef.G.IsEqualTo(guid);
} class NoDefaultConstructorWithChar
{
public NoDefaultConstructorWithChar(char c1, char? c2, char? c3)
{
Char1 = c1;
Char2 = c2;
Char3 = c3;
}
public char Char1 { get; set; }
public char? Char2 { get; set; }
public char? Char3 { get; set; }
} public void TestNoDefaultConstructorWithChar()
{
const char c1 = 'ą';
const char c3 = 'ó';
NoDefaultConstructorWithChar nodef = connection.Query<NoDefaultConstructorWithChar>("select @c1 c1, @c2 c2, @c3 c3", new { c1 = c1, c2 = (char?)null, c3 = c3 }).First();
nodef.Char1.IsEqualTo(c1);
nodef.Char2.IsEqualTo(null);
nodef.Char3.IsEqualTo(c3);
} class NoDefaultConstructorWithEnum
{
public NoDefaultConstructorWithEnum(ShortEnum e1, ShortEnum? n1, ShortEnum? n2)
{
E = e1;
NE1 = n1;
NE2 = n2;
}
public ShortEnum E { get; set; }
public ShortEnum? NE1 { get; set; }
public ShortEnum? NE2 { get; set; }
} public void TestNoDefaultConstructorWithEnum()
{
NoDefaultConstructorWithEnum nodef = connection.Query<NoDefaultConstructorWithEnum>("select cast(2 as smallint) E1, cast(5 as smallint) n1, cast(null as smallint) n2").First();
nodef.E.IsEqualTo(ShortEnum.Two);
nodef.NE1.IsEqualTo(ShortEnum.Five);
nodef.NE2.IsEqualTo(null);
}
#if EXTERNALS
class NoDefaultConstructorWithBinary
{
public System.Data.Linq.Binary Value { get; set; }
public int Ynt { get; set; }
public NoDefaultConstructorWithBinary(System.Data.Linq.Binary val)
{
Value = val;
}
}
public void TestNoDefaultConstructorBinary()
{
byte[] orig = new byte[];
new Random().NextBytes(orig);
var input = new System.Data.Linq.Binary(orig);
var output = connection.Query<NoDefaultConstructorWithBinary>("select @input as val", new { input }).First().Value;
output.ToArray().IsSequenceEqualTo(orig);
}
#endif // http://stackoverflow.com/q/8593871
public void TestAbstractInheritance()
{
var order = connection.Query<AbstractInheritance.ConcreteOrder>("select 1 Internal,2 Protected,3 [Public],4 Concrete").First(); order.Internal.IsEqualTo();
order.ProtectedVal.IsEqualTo();
order.Public.IsEqualTo();
order.Concrete.IsEqualTo();
} public void TestListOfAnsiStrings()
{
var results = connection.Query<string>("select * from (select 'a' str union select 'b' union select 'c') X where str in @strings",
new { strings = new[] { new DbString { IsAnsi = true, Value = "a" }, new DbString { IsAnsi = true, Value = "b" } } }).ToList(); results[].IsEqualTo("a");
results[].IsEqualTo("b");
} public void TestNullableGuidSupport()
{
var guid = connection.Query<Guid?>("select null").First();
guid.IsNull(); guid = Guid.NewGuid();
var guid2 = connection.Query<Guid?>("select @guid", new { guid }).First();
guid.IsEqualTo(guid2);
} public void TestNonNullableGuidSupport()
{
var guid = Guid.NewGuid();
var guid2 = connection.Query<Guid?>("select @guid", new { guid }).First();
Assert.IsTrue(guid == guid2);
} struct Car
{
public enum TrapEnum : int
{
A = ,
B =
}
#pragma warning disable 0649
public string Name;
#pragma warning restore 0649
public int Age { get; set; }
public TrapEnum Trap { get; set; } } struct CarWithAllProps
{
public string Name { get; set; }
public int Age { get; set; } public Car.TrapEnum Trap { get; set; }
} public void TestStructs()
{
var car = connection.Query<Car>("select 'Ford' Name, 21 Age, 2 Trap").First(); car.Age.IsEqualTo();
car.Name.IsEqualTo("Ford");
((int)car.Trap).IsEqualTo();
} public void TestStructAsParam()
{
var car1 = new CarWithAllProps { Name = "Ford", Age = , Trap = Car.TrapEnum.B };
// note Car has Name as a field; parameters only respect properties at the moment
var car2 = connection.Query<CarWithAllProps>("select @Name Name, @Age Age, @Trap Trap", car1).First(); car2.Name.IsEqualTo(car1.Name);
car2.Age.IsEqualTo(car1.Age);
car2.Trap.IsEqualTo(car1.Trap);
} public void SelectListInt()
{
connection.Query<int>("select 1 union all select 2 union all select 3")
.IsSequenceEqualTo(new[] { , , });
}
public void SelectBinary()
{
connection.Query<byte[]>("select cast(1 as varbinary(4))").First().SequenceEqual(new byte[] { });
}
public void PassInIntArray()
{
connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { , , }.AsEnumerable() })
.IsSequenceEqualTo(new[] { , , });
} public void PassInEmptyIntArray()
{
connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] })
.IsSequenceEqualTo(new int[]);
} public void TestSchemaChanged()
{
connection.Execute("create table #dog(Age int, Name nvarchar(max)) insert #dog values(1, 'Alf')");
try
{
var d = connection.Query<Dog>("select * from #dog").Single();
d.Name.IsEqualTo("Alf");
d.Age.IsEqualTo();
connection.Execute("alter table #dog drop column Name");
d = connection.Query<Dog>("select * from #dog").Single();
d.Name.IsNull();
d.Age.IsEqualTo();
}
finally
{
connection.Execute("drop table #dog");
}
} public void TestSchemaChangedMultiMap()
{
connection.Execute("create table #dog(Age int, Name nvarchar(max)) insert #dog values(1, 'Alf')");
try
{
var tuple = connection.Query<Dog, Dog, Tuple<Dog, Dog>>("select * from #dog d1 join #dog d2 on 1=1", (d1, d2) => Tuple.Create(d1, d2), splitOn: "Age").Single(); tuple.Item1.Name.IsEqualTo("Alf");
tuple.Item1.Age.IsEqualTo();
tuple.Item2.Name.IsEqualTo("Alf");
tuple.Item2.Age.IsEqualTo(); connection.Execute("alter table #dog drop column Name");
tuple = connection.Query<Dog, Dog, Tuple<Dog, Dog>>("select * from #dog d1 join #dog d2 on 1=1", (d1, d2) => Tuple.Create(d1, d2), splitOn: "Age").Single(); tuple.Item1.Name.IsNull();
tuple.Item1.Age.IsEqualTo();
tuple.Item2.Name.IsNull();
tuple.Item2.Age.IsEqualTo();
}
finally
{
connection.Execute("drop table #dog");
}
} public void TestReadMultipleIntegersWithSplitOnAny()
{
connection.Query<int, int, int, Tuple<int, int, int>>(
"select 1,2,3 union all select 4,5,6", Tuple.Create, splitOn: "*")
.IsSequenceEqualTo(new[] { Tuple.Create(, , ), Tuple.Create(, , ) });
} public void TestDoubleParam()
{
connection.Query<double>("select @d", new { d = 0.1d }).First()
.IsEqualTo(0.1d);
} public void TestBoolParam()
{
connection.Query<bool>("select @b", new { b = false }).First()
.IsFalse();
} // http://code.google.com/p/dapper-dot-net/issues/detail?id=70
// https://connect.microsoft.com/VisualStudio/feedback/details/381934/sqlparameter-dbtype-dbtype-time-sets-the-parameter-to-sqldbtype-datetime-instead-of-sqldbtype-time
public void TestTimeSpanParam()
{
connection.Query<TimeSpan>("select @ts", new { ts = TimeSpan.FromMinutes() }).First()
.IsEqualTo(TimeSpan.FromMinutes());
} public void TestStrings()
{
connection.Query<string>(@"select 'a' a union select 'b'")
.IsSequenceEqualTo(new[] { "a", "b" });
} // see http://stackoverflow.com/questions/16726709/string-format-with-sql-wildcard-causing-dapper-query-to-break
public void CheckComplexConcat()
{
string end_wildcard = @"
SELECT * FROM #users16726709
WHERE (first_name LIKE CONCAT(@search_term, '%') OR last_name LIKE CONCAT(@search_term, '%'));"; string both_wildcards = @"
SELECT * FROM #users16726709
WHERE (first_name LIKE CONCAT('%', @search_term, '%') OR last_name LIKE CONCAT('%', @search_term, '%'));"; string formatted = @"
SELECT * FROM #users16726709
WHERE (first_name LIKE {0} OR last_name LIKE {0});"; string use_end_only = @"CONCAT(@search_term, '%')";
string use_both = @"CONCAT('%', @search_term, '%')"; // if true, slower query due to not being able to use indices, but will allow searching inside strings
bool allow_start_wildcards = false; string query = String.Format(formatted, allow_start_wildcards ? use_both : use_end_only);
string term = "F"; // the term the user searched for connection.Execute(@"create table #users16726709 (first_name varchar(200), last_name varchar(200))
insert #users16726709 values ('Fred','Bloggs') insert #users16726709 values ('Tony','Farcus') insert #users16726709 values ('Albert','TenoF')"); // Using Dapper
connection.Query(end_wildcard, new { search_term = term }).Count().IsEqualTo();
connection.Query(both_wildcards, new { search_term = term }).Count().IsEqualTo();
connection.Query(query, new { search_term = term }).Count().IsEqualTo(); } enum EnumParam : short
{
None, A, B
}
class EnumParamObject
{
public EnumParam A { get; set; }
public EnumParam? B { get; set; }
public EnumParam? C { get; set; }
}
class EnumParamObjectNonNullable
{
public EnumParam A { get; set; }
public EnumParam? B { get; set; }
public EnumParam? C { get; set; }
}
public void TestEnumParamsWithNullable()
{
EnumParam a = EnumParam.A;
EnumParam? b = EnumParam.B, c = null;
var obj = connection.Query<EnumParamObject>("select @a as A, @b as B, @c as C",
new { a, b, c }).Single();
obj.A.IsEqualTo(EnumParam.A);
obj.B.IsEqualTo(EnumParam.B);
obj.C.IsEqualTo(null);
}
public void TestEnumParamsWithoutNullable()
{
EnumParam a = EnumParam.A;
EnumParam b = EnumParam.B, c = ;
var obj = connection.Query<EnumParamObjectNonNullable>("select @a as A, @b as B, @c as C",
new { a, b, c }).Single();
obj.A.IsEqualTo(EnumParam.A);
obj.B.IsEqualTo(EnumParam.B);
obj.C.IsEqualTo((EnumParam));
}
public class Dog
{
public int? Age { get; set; }
public Guid Id { get; set; }
public string Name { get; set; }
public float? Weight { get; set; } public int IgnoredProperty { get { return ; } }
} public void TestExtraFields()
{
var guid = Guid.NewGuid();
var dog = connection.Query<Dog>("select '' as Extra, 1 as Age, 0.1 as Name1 , Id = @id", new { id = guid }); dog.Count()
.IsEqualTo(); dog.First().Age
.IsEqualTo(); dog.First().Id
.IsEqualTo(guid);
}
#if EXTERNALS
// see http://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
using (var conn = ConnectViaOledb())
{
var row = conn.Query("select Id = ?, Age = ?",
new { foo = , bar = } // these names DO NOT MATTER!!!
).Single();
int age = row.Age;
int id = row.Id;
age.IsEqualTo();
id.IsEqualTo();
}
} System.Data.OleDb.OleDbConnection ConnectViaOledb()
{
var conn = new System.Data.OleDb.OleDbConnection(Program.OleDbConnectionString);
conn.Open();
return conn;
}
#endif
public void TestStrongType()
{
var guid = Guid.NewGuid();
var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid }); dog.Count()
.IsEqualTo(); dog.First().Age
.IsNull(); dog.First().Id
.IsEqualTo(guid);
} public void TestSimpleNull()
{
connection.Query<DateTime?>("select null").First().IsNull();
} public void TestExpando()
{
var rows = connection.Query("select 1 A, 2 B union all select 3, 4").ToList(); ((int)rows[].A)
.IsEqualTo(); ((int)rows[].B)
.IsEqualTo(); ((int)rows[].A)
.IsEqualTo(); ((int)rows[].B)
.IsEqualTo();
} public void TestStringList()
{
connection.Query<string>("select * from (select 'a' as x union all select 'b' union all select 'c') as T where x in @strings", new { strings = new[] { "a", "b", "c" } })
.IsSequenceEqualTo(new[] { "a", "b", "c" }); connection.Query<string>("select * from (select 'a' as x union all select 'b' union all select 'c') as T where x in @strings", new { strings = new string[] })
.IsSequenceEqualTo(new string[]);
} public void TestExecuteCommand()
{
connection.Execute(@"
set nocount on
create table #t(i int)
set nocount off
insert #t
select @a a union all select @b
set nocount on
drop table #t", new { a = , b = }).IsEqualTo();
}
public void TestExecuteCommandWithHybridParameters()
{
var p = new DynamicParameters(new { a = , b = });
p.Add("c", dbType: DbType.Int32, direction: ParameterDirection.Output);
connection.Execute(@"set @c = @a + @b", p);
p.Get<int>("@c").IsEqualTo();
}
public void TestExecuteMultipleCommand()
{
connection.Execute("create table #t(i int)");
try
{
int tally = connection.Execute(@"insert #t (i) values(@a)", new[] { new { a = }, new { a = }, new { a = }, new { a = } });
int sum = connection.Query<int>("select sum(i) from #t").First();
tally.IsEqualTo();
sum.IsEqualTo();
}
finally
{
connection.Execute("drop table #t");
}
} class Student
{
public string Name { get; set; }
public int Age { get; set; }
} public void TestExecuteMultipleCommandStrongType()
{
connection.Execute("create table #t(Name nvarchar(max), Age int)");
try
{
int tally = connection.Execute(@"insert #t (Name,Age) values(@Name, @Age)", new List<Student>
{
new Student{Age = , Name = "sam"},
new Student{Age = , Name = "bob"}
});
int sum = connection.Query<int>("select sum(Age) from #t").First();
tally.IsEqualTo();
sum.IsEqualTo();
}
finally
{
connection.Execute("drop table #t");
}
} public void TestExecuteMultipleCommandObjectArray()
{
connection.Execute("create table #t(i int)");
int tally = connection.Execute(@"insert #t (i) values(@a)", new object[] { new { a = }, new { a = }, new { a = }, new { a = } });
int sum = connection.Query<int>("select sum(i) from #t drop table #t").First();
tally.IsEqualTo();
sum.IsEqualTo();
} public void TestMassiveStrings()
{
var str = new string('X', );
connection.Query<string>("select @a", new { a = str }).First()
.IsEqualTo(str);
} class TestObj
{
public int _internal;
internal int Internal { set { _internal = value; } } public int _priv;
private int Priv { set { _priv = value; } } private int PrivGet { get { return _priv; } }
} public void TestSetInternal()
{
connection.Query<TestObj>("select 10 as [Internal]").First()._internal.IsEqualTo();
} public void TestSetPrivate()
{
connection.Query<TestObj>("select 10 as [Priv]").First()._priv.IsEqualTo();
} public void TestExpandWithNullableFields()
{
var row = connection.Query("select null A, 2 B").Single(); ((int?)row.A)
.IsNull(); ((int?)row.B)
.IsEqualTo();
} public void TestEnumeration()
{
var en = connection.Query<int>("select 1 as one union all select 2 as one", buffered: false);
var i = en.GetEnumerator();
i.MoveNext(); bool gotException = false;
try
{
var x = connection.Query<int>("select 1 as one", buffered: false).First();
}
catch (Exception)
{
gotException = true;
} while (i.MoveNext())
{ } // should not exception, since enumerated
en = connection.Query<int>("select 1 as one", buffered: false); gotException.IsTrue();
} public void TestEnumerationDynamic()
{
var en = connection.Query("select 1 as one union all select 2 as one", buffered: false);
var i = en.GetEnumerator();
i.MoveNext(); bool gotException = false;
try
{
var x = connection.Query("select 1 as one", buffered: false).First();
}
catch (Exception)
{
gotException = true;
} while (i.MoveNext())
{ } // should not exception, since enumertated
en = connection.Query("select 1 as one", buffered: false); gotException.IsTrue();
} public void TestNakedBigInt()
{
long foo = ;
var result = connection.Query<long>("select @foo", new { foo }).Single();
foo.IsEqualTo(result);
} public void TestBigIntMember()
{
long foo = ;
var result = connection.Query<WithBigInt>(@"
declare @bar table(Value bigint)
insert @bar values (@foo)
select * from @bar", new { foo }).Single();
result.Value.IsEqualTo(foo);
}
class WithBigInt
{
public long Value { get; set; }
} class User
{
public int Id { get; set; }
public string Name { get; set; }
}
class Post
{
public int Id { get; set; }
public User Owner { get; set; }
public string Content { get; set; }
public Comment Comment { get; set; }
}
public void TestMultiMap()
{
var createSql = @"
create table #Users (Id int, Name varchar(20))
create table #Posts (Id int, OwnerId int, Content varchar(20))
insert #Users values(99, 'Sam')
insert #Users values(2, 'I am')
insert #Posts values(1, 99, 'Sams Post1')
insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')
";
connection.Execute(createSql);
try
{
var sql =
@"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id"; var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post; }).ToList();
var p = data.First(); p.Content.IsEqualTo("Sams Post1");
p.Id.IsEqualTo();
p.Owner.Name.IsEqualTo("Sam");
p.Owner.Id.IsEqualTo(); data[].Owner.IsNull();
}
finally
{
connection.Execute("drop table #Users drop table #Posts");
}
} class ReviewBoard
{
public int Id { get; set; }
public string Name { get; set; }
public User User1 { get; set; }
public User User2 { get; set; }
public User User3 { get; set; }
public User User4 { get; set; }
public User User5 { get; set; }
public User User6 { get; set; }
public User User7 { get; set; }
public User User8 { get; set; }
public User User9 { get; set; }
} public void TestMultiMapArbitraryMaps()
{
// please excuse the trite example, but it is easier to follow than a more real-world one
var createSql = @"
create table #ReviewBoards (Id int, Name varchar(20), User1Id int, User2Id int, User3Id int, User4Id int, User5Id int, User6Id int, User7Id int, User8Id int, User9Id int)
create table #Users (Id int, Name varchar(20))
insert #Users values(1, 'User 1')
insert #Users values(2, 'User 2')
insert #Users values(3, 'User 3')
insert #Users values(4, 'User 4')
insert #Users values(5, 'User 5')
insert #Users values(6, 'User 6')
insert #Users values(7, 'User 7')
insert #Users values(8, 'User 8')
insert #Users values(9, 'User 9')
insert #ReviewBoards values(1, 'Review Board 1', 1, 2, 3, 4, 5, 6, 7, 8, 9)
";
connection.Execute(createSql);
try
{
var sql = @"
select
rb.Id, rb.Name,
u1.*, u2.*, u3.*, u4.*, u5.*, u6.*, u7.*, u8.*, u9.*
from #ReviewBoards rb
inner join #Users u1 on u1.Id = rb.User1Id
inner join #Users u2 on u2.Id = rb.User2Id
inner join #Users u3 on u3.Id = rb.User3Id
inner join #Users u4 on u4.Id = rb.User4Id
inner join #Users u5 on u5.Id = rb.User5Id
inner join #Users u6 on u6.Id = rb.User6Id
inner join #Users u7 on u7.Id = rb.User7Id
inner join #Users u8 on u8.Id = rb.User8Id
inner join #Users u9 on u9.Id = rb.User9Id
"; var types = new[] { typeof(ReviewBoard), typeof(User), typeof(User), typeof(User), typeof(User), typeof(User), typeof(User), typeof(User), typeof(User), typeof(User) }; Func<object[], ReviewBoard> mapper = (objects) =>
{
var board = (ReviewBoard)objects[];
board.User1 = (User)objects[];
board.User2 = (User)objects[];
board.User3 = (User)objects[];
board.User4 = (User)objects[];
board.User5 = (User)objects[];
board.User6 = (User)objects[];
board.User7 = (User)objects[];
board.User8 = (User)objects[];
board.User9 = (User)objects[];
return board;
}; var data = connection.Query<ReviewBoard>(sql, types, mapper).ToList(); var p = data.First();
p.Id.IsEqualTo();
p.Name.IsEqualTo("Review Board 1");
p.User1.Id.IsEqualTo();
p.User2.Id.IsEqualTo();
p.User3.Id.IsEqualTo();
p.User4.Id.IsEqualTo();
p.User5.Id.IsEqualTo();
p.User6.Id.IsEqualTo();
p.User7.Id.IsEqualTo();
p.User8.Id.IsEqualTo();
p.User9.Id.IsEqualTo();
p.User1.Name.IsEqualTo("User 1");
p.User2.Name.IsEqualTo("User 2");
p.User3.Name.IsEqualTo("User 3");
p.User4.Name.IsEqualTo("User 4");
p.User5.Name.IsEqualTo("User 5");
p.User6.Name.IsEqualTo("User 6");
p.User7.Name.IsEqualTo("User 7");
p.User8.Name.IsEqualTo("User 8");
p.User9.Name.IsEqualTo("User 9");
}
finally
{
connection.Execute("drop table #Users drop table #ReviewBoards");
}
} public void TestMultiMapGridReader()
{
var createSql = @"
create table #Users (Id int, Name varchar(20))
create table #Posts (Id int, OwnerId int, Content varchar(20))
insert #Users values(99, 'Sam')
insert #Users values(2, 'I am')
insert #Posts values(1, 99, 'Sams Post1')
insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')
";
connection.Execute(createSql); var sql =
@"select p.*, u.Id, u.Name + '0' Name from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id
select p.*, u.Id, u.Name + '1' Name from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id
"; var grid = connection.QueryMultiple(sql); for (int i = ; i < ; i++)
{
var data = grid.Read<Post, User, Post>((post, user) => { post.Owner = user; return post; }).ToList();
var p = data.First(); p.Content.IsEqualTo("Sams Post1");
p.Id.IsEqualTo();
p.Owner.Name.IsEqualTo("Sam" + i);
p.Owner.Id.IsEqualTo(); data[].Owner.IsNull();
} connection.Execute("drop table #Users drop table #Posts"); } public void TestQueryMultipleBuffered()
{
using (var grid = connection.QueryMultiple("select 1; select 2; select @x; select 4", new { x = }))
{
var a = grid.Read<int>();
var b = grid.Read<int>();
var c = grid.Read<int>();
var d = grid.Read<int>(); a.Single().Equals();
b.Single().Equals();
c.Single().Equals();
d.Single().Equals();
}
} public void TestQueryMultipleNonBufferedIncorrectOrder()
{
using (var grid = connection.QueryMultiple("select 1; select 2; select @x; select 4", new { x = }))
{
var a = grid.Read<int>(false);
try
{
var b = grid.Read<int>(false);
throw new InvalidOperationException(); // should have thrown
}
catch (InvalidOperationException)
{
// that's expected
} }
}
public void TestQueryMultipleNonBufferedCcorrectOrder()
{
using (var grid = connection.QueryMultiple("select 1; select 2; select @x; select 4", new { x = }))
{
var a = grid.Read<int>(false).Single();
var b = grid.Read<int>(false).Single();
var c = grid.Read<int>(false).Single();
var d = grid.Read<int>(false).Single(); a.Equals();
b.Equals();
c.Equals();
d.Equals();
}
}
public void TestMultiMapDynamic()
{
var createSql = @"
create table #Users (Id int, Name varchar(20))
create table #Posts (Id int, OwnerId int, Content varchar(20))
insert #Users values(99, 'Sam')
insert #Users values(2, 'I am')
insert #Posts values(1, 99, 'Sams Post1')
insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')
";
connection.Execute(createSql); var sql =
@"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id"; var data = connection.Query<dynamic, dynamic, dynamic>(sql, (post, user) => { post.Owner = user; return post; }).ToList();
var p = data.First(); // hairy extension method support for dynamics
((string)p.Content).IsEqualTo("Sams Post1");
((int)p.Id).IsEqualTo();
((string)p.Owner.Name).IsEqualTo("Sam");
((int)p.Owner.Id).IsEqualTo(); ((object)data[].Owner).IsNull(); connection.Execute("drop table #Users drop table #Posts");
} 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; }
}
public void TestMultiMapWithSplit() // http://stackoverflow.com/q/6056778/23354
{
var sql = @"select 1 as id, 'abc' as name, 2 as id, 'def' as name";
var product = connection.Query<Product, Category, Product>(sql, (prod, cat) =>
{
prod.Category = cat;
return prod;
}).First();
// assertions
product.Id.IsEqualTo();
product.Name.IsEqualTo("abc");
product.Category.Id.IsEqualTo();
product.Category.Name.IsEqualTo("def");
}
public void TestMultiMapWithSplitWithNullValue() // http://stackoverflow.com/q/10744728/449906
{
var sql = @"select 1 as id, 'abc' as name, NULL as description, 'def' as name";
var product = connection.Query<Product, Category, Product>(sql, (prod, cat) =>
{
prod.Category = cat;
return prod;
}, splitOn: "description").First();
// assertions
product.Id.IsEqualTo();
product.Name.IsEqualTo("abc");
product.Category.IsNull();
}
public void TestMultiMapWithSplitWithNullValueAndSpoofColumn() // http://stackoverflow.com/q/10744728/449906
{
var sql = @"select 1 as id, 'abc' as name, 1 as spoof, NULL as description, 'def' as name";
var product = connection.Query<Product, Category, Product>(sql, (prod, cat) =>
{
prod.Category = cat;
return prod;
}, splitOn: "spoof").First();
// assertions
product.Id.IsEqualTo();
product.Name.IsEqualTo("abc");
product.Category.IsNotNull();
product.Category.Id.IsEqualTo();
product.Category.Name.IsEqualTo("def");
product.Category.Description.IsNull();
}
public void TestFieldsAndPrivates()
{
var data = connection.Query<TestFieldCaseAndPrivatesEntity>(
@"select a=1,b=2,c=3,d=4,f='5'").Single(); data.a.IsEqualTo();
data.GetB().IsEqualTo();
data.c.IsEqualTo();
data.GetD().IsEqualTo();
data.e.IsEqualTo(); } #if EXTERNALS
public void ExecuteReader()
{
var dt = new DataTable();
dt.Load(connection.ExecuteReader("select 3 as [three], 4 as [four]"));
dt.Columns.Count.IsEqualTo();
dt.Columns[].ColumnName.IsEqualTo("three");
dt.Columns[].ColumnName.IsEqualTo("four");
dt.Rows.Count.IsEqualTo();
((int)dt.Rows[][]).IsEqualTo();
((int)dt.Rows[][]).IsEqualTo();
}
#endif
private class TestFieldCaseAndPrivatesEntity
{
public int a { get; set; }
private int b { get; set; }
public int GetB() { return b; }
public int c = ;
private int d = ;
public int GetD() { return d; }
public int e { get; set; }
private string f
{
get { return e.ToString(); }
set { e = int.Parse(value); }
}
} public void TestMultiReaderBasic()
{
var sql = @"select 1 as Id union all select 2 as Id select 'abc' as name select 1 as Id union all select 2 as Id";
int i, j;
string s;
using (var multi = connection.QueryMultiple(sql))
{
i = multi.Read<int>().First();
s = multi.Read<string>().Single();
j = multi.Read<int>().Sum();
}
Assert.IsEqualTo(i, );
Assert.IsEqualTo(s, "abc");
Assert.IsEqualTo(j, );
}
public void TestMultiMappingVariations()
{
var sql = @"select 1 as Id, 'a' as Content, 2 as Id, 'b' as Content, 3 as Id, 'c' as Content, 4 as Id, 'd' as Content, 5 as Id, 'e' as Content"; var order = connection.Query<dynamic, dynamic, dynamic, dynamic>(sql, (o, owner, creator) => { o.Owner = owner; o.Creator = creator; return o; }).First(); Assert.IsEqualTo(order.Id, );
Assert.IsEqualTo(order.Content, "a");
Assert.IsEqualTo(order.Owner.Id, );
Assert.IsEqualTo(order.Owner.Content, "b");
Assert.IsEqualTo(order.Creator.Id, );
Assert.IsEqualTo(order.Creator.Content, "c"); order = connection.Query<dynamic, dynamic, dynamic, dynamic, dynamic>(sql, (o, owner, creator, address) =>
{
o.Owner = owner;
o.Creator = creator;
o.Owner.Address = address;
return o;
}).First(); Assert.IsEqualTo(order.Id, );
Assert.IsEqualTo(order.Content, "a");
Assert.IsEqualTo(order.Owner.Id, );
Assert.IsEqualTo(order.Owner.Content, "b");
Assert.IsEqualTo(order.Creator.Id, );
Assert.IsEqualTo(order.Creator.Content, "c");
Assert.IsEqualTo(order.Owner.Address.Id, );
Assert.IsEqualTo(order.Owner.Address.Content, "d"); order = connection.Query<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>(sql, (a, b, c, d, e) => { a.B = b; a.C = c; a.C.D = d; a.E = e; return a; }).First(); Assert.IsEqualTo(order.Id, );
Assert.IsEqualTo(order.Content, "a");
Assert.IsEqualTo(order.B.Id, );
Assert.IsEqualTo(order.B.Content, "b");
Assert.IsEqualTo(order.C.Id, );
Assert.IsEqualTo(order.C.Content, "c");
Assert.IsEqualTo(order.C.D.Id, );
Assert.IsEqualTo(order.C.D.Content, "d");
Assert.IsEqualTo(order.E.Id, );
Assert.IsEqualTo(order.E.Content, "e"); } class InheritanceTest1
{
public string Base1 { get; set; }
public string Base2 { get; private set; }
} class InheritanceTest2 : InheritanceTest1
{
public string Derived1 { get; set; }
public string Derived2 { get; private set; }
} public void TestInheritance()
{
// Test that inheritance works.
var list = connection.Query<InheritanceTest2>("select 'One' as Derived1, 'Two' as Derived2, 'Three' as Base1, 'Four' as Base2");
list.First().Derived1.IsEqualTo("One");
list.First().Derived2.IsEqualTo("Two");
list.First().Base1.IsEqualTo("Three");
list.First().Base2.IsEqualTo("Four");
} public class PostCE
{
public int ID { get; set; }
public string Title { get; set; }
public string Body { get; set; } public AuthorCE Author { get; set; }
} public class AuthorCE
{
public int ID { get; set; }
public string Name { get; set; }
}
#if EXTERNALS
public void MultiRSSqlCE()
{
if (File.Exists("Test.sdf"))
File.Delete("Test.sdf"); var cnnStr = "Data Source = Test.sdf;";
var engine = new SqlCeEngine(cnnStr);
engine.CreateDatabase(); using (var cnn = new SqlCeConnection(cnnStr))
{
cnn.Open(); cnn.Execute("create table Posts (ID int, Title nvarchar(50), Body nvarchar(50), AuthorID int)");
cnn.Execute("create table Authors (ID int, Name nvarchar(50))"); cnn.Execute("insert Posts values (1,'title','body',1)");
cnn.Execute("insert Posts values(2,'title2','body2',null)");
cnn.Execute("insert Authors values(1,'sam')"); var data = cnn.Query<PostCE, AuthorCE, PostCE>(@"select * from Posts p left join Authors a on a.ID = p.AuthorID", (post, author) => { post.Author = author; return post; }).ToList();
var firstPost = data.First();
firstPost.Title.IsEqualTo("title");
firstPost.Author.Name.IsEqualTo("sam");
data[].Author.IsNull();
cnn.Close();
}
}
#endif
enum TestEnum : byte
{
Bla =
}
class TestEnumClass
{
public TestEnum? EnumEnum { get; set; }
}
class TestEnumClassNoNull
{
public TestEnum EnumEnum { get; set; }
}
public void TestEnumWeirdness()
{
connection.Query<TestEnumClass>("select null as [EnumEnum]").First().EnumEnum.IsEqualTo(null);
connection.Query<TestEnumClass>("select cast(1 as tinyint) as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
}
public void TestEnumStrings()
{
connection.Query<TestEnumClassNoNull>("select 'BLA' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
connection.Query<TestEnumClassNoNull>("select 'bla' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla); connection.Query<TestEnumClass>("select 'BLA' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
connection.Query<TestEnumClass>("select 'bla' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
} public void TestSupportForDynamicParameters()
{
var p = new DynamicParameters();
p.Add("name", "bob");
p.Add("age", dbType: DbType.Int32, direction: ParameterDirection.Output); connection.Query<string>("set @age = 11 select @name", p).First().IsEqualTo("bob"); p.Get<int>("age").IsEqualTo();
} public void TestSupportForDynamicParametersOutputExpressions()
{
var bob = new Person { Name = "bob", PersonId = , Address = new Address { PersonId = } }; var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId); connection.Execute(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId", p); bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo();
bob.NumberOfLegs.IsEqualTo();
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo();
}
public void TestSupportForDynamicParametersOutputExpressions_Scalar()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = , Address = new Address { PersonId = } }; var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId); var result = (int)connection.ExecuteScalar(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p); bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo();
bob.NumberOfLegs.IsEqualTo();
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo();
result.IsEqualTo();
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_Buffered()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = , Address = new Address { PersonId = } }; var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId); var result = connection.Query<int>(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p, buffered: true).Single(); bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo();
bob.NumberOfLegs.IsEqualTo();
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo();
result.IsEqualTo();
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_NonBuffered()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = , Address = new Address { PersonId = } }; var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId); var result = connection.Query<int>(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p, buffered: false).Single(); bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo();
bob.NumberOfLegs.IsEqualTo();
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo();
result.IsEqualTo();
}
} public void TestSupportForDynamicParametersOutputExpressions_QueryMultiple()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = , Address = new Address { PersonId = } }; var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId); int x, y;
using (var multi = connection.QueryMultiple(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
select 42
select 17
SET @AddressPersonId = @PersonId", p))
{
x = multi.Read<int>().Single();
y = multi.Read<int>().Single();
} bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo();
bob.NumberOfLegs.IsEqualTo();
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo();
x.IsEqualTo();
y.IsEqualTo();
}
}
public void TestSupportForExpandoObjectParameters()
{
dynamic p = new ExpandoObject();
p.name = "bob";
object parameters = p;
string result = connection.Query<string>("select @name", parameters).First();
result.IsEqualTo("bob");
} public void TestProcSupport()
{
var p = new DynamicParameters();
p.Add("a", );
p.Add("b", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue); connection.Execute(@"create proc #TestProc
@a int,
@b int output
as
begin
set @b = 999
select 1111
return @a
end");
connection.Query<int>("#TestProc", p, commandType: CommandType.StoredProcedure).First().IsEqualTo(); p.Get<int>("c").IsEqualTo();
p.Get<int>("b").IsEqualTo(); } public void TestDbString()
{
var obj = connection.Query("select datalength(@a) as a, datalength(@b) as b, datalength(@c) as c, datalength(@d) as d, datalength(@e) as e, datalength(@f) as f",
new
{
a = new DbString { Value = "abcde", IsFixedLength = true, Length = , IsAnsi = true },
b = new DbString { Value = "abcde", IsFixedLength = true, Length = , IsAnsi = false },
c = new DbString { Value = "abcde", IsFixedLength = false, Length = , IsAnsi = true },
d = new DbString { Value = "abcde", IsFixedLength = false, Length = , IsAnsi = false },
e = new DbString { Value = "abcde", IsAnsi = true },
f = new DbString { Value = "abcde", IsAnsi = false },
}).First();
((int)obj.a).IsEqualTo();
((int)obj.b).IsEqualTo();
((int)obj.c).IsEqualTo();
((int)obj.d).IsEqualTo();
((int)obj.e).IsEqualTo();
((int)obj.f).IsEqualTo();
} class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public string Occupation { get; private set; }
public int NumberOfLegs = ;
public Address Address { get; set; }
} class Address
{
public int AddressId { get; set; }
public string Name { get; set; }
public int PersonId { get; set; }
} class Extra
{
public int Id { get; set; }
public string Name { get; set; }
} public void TestFlexibleMultiMapping()
{
var sql =
@"select
1 as PersonId, 'bob' as Name,
2 as AddressId, 'abc street' as Name, 1 as PersonId,
3 as Id, 'fred' as Name
";
var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address, Extra>>
(sql, (p, a, e) => Tuple.Create(p, a, e), splitOn: "AddressId,Id").First(); personWithAddress.Item1.PersonId.IsEqualTo();
personWithAddress.Item1.Name.IsEqualTo("bob");
personWithAddress.Item2.AddressId.IsEqualTo();
personWithAddress.Item2.Name.IsEqualTo("abc street");
personWithAddress.Item2.PersonId.IsEqualTo();
personWithAddress.Item3.Id.IsEqualTo();
personWithAddress.Item3.Name.IsEqualTo("fred"); } public void TestMultiMappingWithSplitOnSpaceBetweenCommas()
{
var sql = @"select
1 as PersonId, 'bob' as Name,
2 as AddressId, 'abc street' as Name, 1 as PersonId,
3 as Id, 'fred' as Name
";
var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address, Extra>>
(sql, (p, a, e) => Tuple.Create(p, a, e), splitOn: "AddressId, Id").First(); personWithAddress.Item1.PersonId.IsEqualTo();
personWithAddress.Item1.Name.IsEqualTo("bob");
personWithAddress.Item2.AddressId.IsEqualTo();
personWithAddress.Item2.Name.IsEqualTo("abc street");
personWithAddress.Item2.PersonId.IsEqualTo();
personWithAddress.Item3.Id.IsEqualTo();
personWithAddress.Item3.Name.IsEqualTo("fred"); } public void TestMultiMappingWithNonReturnedProperty()
{
var sql = @"select
1 as PostId, 'Title' as Title,
2 as BlogId, 'Blog' as Title";
var postWithBlog = connection.Query<Post_DupeProp, Blog_DupeProp, Post_DupeProp>(sql,
(p, b) =>
{
p.Blog = b;
return p;
}, splitOn: "BlogId").First(); postWithBlog.PostId.IsEqualTo();
postWithBlog.Title.IsEqualTo("Title");
postWithBlog.Blog.BlogId.IsEqualTo();
postWithBlog.Blog.Title.IsEqualTo("Blog");
} class Post_DupeProp
{
public int PostId { get; set; }
public string Title { get; set; }
public int BlogId { get; set; }
public Blog_DupeProp Blog { get; set; }
} class Blog_DupeProp
{
public int BlogId { get; set; }
public string Title { get; set; }
} public void TestFastExpandoSupportsIDictionary()
{
var row = connection.Query("select 1 A, 'two' B").First() as IDictionary<string, object>;
row["A"].IsEqualTo();
row["B"].IsEqualTo("two");
} class PrivateDan
{
public int Shadow { get; set; }
private string ShadowInDB
{
set
{
Shadow = value == "one" ? : ;
}
}
}
public void TestDapperSetsPrivates()
{
connection.Query<PrivateDan>("select 'one' ShadowInDB").First().Shadow.IsEqualTo();
} class IntDynamicParam : Dapper.SqlMapper.IDynamicParameters
{
IEnumerable<int> numbers;
public IntDynamicParam(IEnumerable<int> numbers)
{
this.numbers = numbers;
} public void AddParameters(IDbCommand command, Dapper.SqlMapper.Identity identity)
{
var sqlCommand = (SqlCommand)command;
sqlCommand.CommandType = CommandType.StoredProcedure; List<Microsoft.SqlServer.Server.SqlDataRecord> number_list = new List<Microsoft.SqlServer.Server.SqlDataRecord>(); // Create an SqlMetaData object that describes our table type.
Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int) }; foreach (int n in numbers)
{
// Create a new record, using the metadata array above.
Microsoft.SqlServer.Server.SqlDataRecord rec = new Microsoft.SqlServer.Server.SqlDataRecord(tvp_definition);
rec.SetInt32(, n); // Set the value.
number_list.Add(rec); // Add it to the list.
} // 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; }
}
#if EXTERNALS
// SQL Server specific test to demonstrate TVP
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"); var nums = connection.Query<int>("get_ints", new IntDynamicParam(new int[] { , , })).ToList();
nums[].IsEqualTo();
nums[].IsEqualTo();
nums[].IsEqualTo();
nums.Count.IsEqualTo(); }
finally
{
try
{
connection.Execute("DROP PROC get_ints");
}
finally
{
connection.Execute("DROP TYPE int_list_type");
}
}
} class DynamicParameterWithIntTVP : Dapper.DynamicParameters, Dapper.SqlMapper.IDynamicParameters
{
IEnumerable<int> numbers;
public DynamicParameterWithIntTVP(IEnumerable<int> numbers)
{
this.numbers = numbers;
} public new void AddParameters(IDbCommand command, Dapper.SqlMapper.Identity identity)
{
base.AddParameters(command, identity); var sqlCommand = (SqlCommand)command;
sqlCommand.CommandType = CommandType.StoredProcedure; List<Microsoft.SqlServer.Server.SqlDataRecord> number_list = new List<Microsoft.SqlServer.Server.SqlDataRecord>(); // Create an SqlMetaData object that describes our table type.
Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int) }; foreach (int n in numbers)
{
// Create a new record, using the metadata array above.
Microsoft.SqlServer.Server.SqlDataRecord rec = new Microsoft.SqlServer.Server.SqlDataRecord(tvp_definition);
rec.SetInt32(, n); // Set the value.
number_list.Add(rec); // Add it to the list.
} // 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; }
} 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"); var dynamicParameters = new DynamicParameterWithIntTVP(new int[] { , , });
dynamicParameters.AddDynamicParams(new { stringParam = "stringParam", dateParam = new DateTime(, , ) }); var results = connection.Query("get_values", dynamicParameters, commandType: CommandType.StoredProcedure).ToList();
results.Count.IsEqualTo();
for (int i = ; i < results.Count; i++)
{
var result = results[i];
Assert.IsEqualTo(i + , result.n);
Assert.IsEqualTo("stringParam", result.stringParam);
Assert.IsEqualTo(new DateTime(, , ), result.dateParam);
} }
finally
{
try
{
connection.Execute("DROP PROC get_values");
}
finally
{
connection.Execute("DROP TYPE int_list_type");
}
}
}
#endif
class IntCustomParam : Dapper.SqlMapper.ICustomQueryParameter
{
IEnumerable<int> numbers;
public IntCustomParam(IEnumerable<int> numbers)
{
this.numbers = numbers;
} public void AddParameter(IDbCommand command, string name)
{
var sqlCommand = (SqlCommand)command;
sqlCommand.CommandType = CommandType.StoredProcedure; List<Microsoft.SqlServer.Server.SqlDataRecord> number_list = new List<Microsoft.SqlServer.Server.SqlDataRecord>(); // Create an SqlMetaData object that describes our table type.
Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int) }; foreach (int n in numbers)
{
// Create a new record, using the metadata array above.
Microsoft.SqlServer.Server.SqlDataRecord rec = new Microsoft.SqlServer.Server.SqlDataRecord(tvp_definition);
rec.SetInt32(, n); // Set the value.
number_list.Add(rec); // Add it to the list.
} // Add the table parameter.
var p = sqlCommand.Parameters.Add(name, SqlDbType.Structured);
p.Direction = ParameterDirection.Input;
p.TypeName = "int_list_type";
p.Value = number_list;
}
}
#if EXTERNALS
public void TestTVPWithAnonymousObject()
{
try
{
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 nums = connection.Query<int>("get_ints", new { integers = new IntCustomParam(new int[] { , , }) }, commandType: CommandType.StoredProcedure).ToList();
nums[].IsEqualTo();
nums[].IsEqualTo();
nums[].IsEqualTo();
nums.Count.IsEqualTo(); }
finally
{
try
{
connection.Execute("DROP PROC get_ints");
}
finally
{
connection.Execute("DROP TYPE int_list_type");
}
}
}
#endif class Parent
{
public int Id { get; set; }
public readonly List<Child> Children = new List<Child>();
}
class Child
{
public int Id { get; set; }
}
public void ParentChildIdentityAssociations()
{
var lookup = new Dictionary<int, Parent>();
var parents = connection.Query<Parent, Child, Parent>(@"select 1 as [Id], 1 as [Id] union all select 1,2 union all select 2,3 union all select 1,4 union all select 3,5",
(parent, child) =>
{
Parent found;
if (!lookup.TryGetValue(parent.Id, out found))
{
lookup.Add(parent.Id, found = parent);
}
found.Children.Add(child);
return found;
}).Distinct().ToDictionary(p => p.Id);
parents.Count().IsEqualTo();
parents[].Children.Select(c => c.Id).SequenceEqual(new[] { , , }).IsTrue();
parents[].Children.Select(c => c.Id).SequenceEqual(new[] { }).IsTrue();
parents[].Children.Select(c => c.Id).SequenceEqual(new[] { }).IsTrue();
} /* TODO:
*
public void TestMagicParam()
{
// magic params allow you to pass in single params without using an anon class
// this test fails for now, but I would like to support a single param by parsing the sql with regex and remapping.
var first = connection.Query("select @a as a", 1).First();
Assert.IsEqualTo(first.a, 1);
}
* */ class WithBizarreData
{
public GenericUriParser Foo { get; set; }
public int Bar { get; set; }
} public void TestUnexpectedDataMessage()
{
string msg = null;
try
{
connection.Query<int>("select count(1) where 1 = @Foo", new WithBizarreData { Foo = new GenericUriParser(GenericUriParserOptions.Default), Bar = }).First(); }
catch (Exception ex)
{
msg = ex.Message;
}
msg.IsEqualTo("The member Foo of type System.GenericUriParser cannot be used as a parameter value");
} public void TestUnexpectedButFilteredDataMessage()
{
int i = connection.Query<int>("select @Bar", new WithBizarreData { Foo = new GenericUriParser(GenericUriParserOptions.Default), Bar = }).Single(); i.IsEqualTo();
} class WithCharValue
{
public char Value { get; set; }
public char? ValueNullable { get; set; }
}
public void TestCharInputAndOutput()
{
const char test = '〠';
char c = connection.Query<char>("select @c", new { c = test }).Single(); c.IsEqualTo(test); var obj = connection.Query<WithCharValue>("select @Value as Value", new WithCharValue { Value = c }).Single(); obj.Value.IsEqualTo(test);
}
public void TestNullableCharInputAndOutputNonNull()
{
char? test = '〠';
char? c = connection.Query<char?>("select @c", new { c = test }).Single(); c.IsEqualTo(test); var obj = connection.Query<WithCharValue>("select @ValueNullable as ValueNullable", new WithCharValue { ValueNullable = c }).Single(); obj.ValueNullable.IsEqualTo(test);
}
public void TestNullableCharInputAndOutputNull()
{
char? test = null;
char? c = connection.Query<char?>("select @c", new { c = test }).Single(); c.IsEqualTo(test); var obj = connection.Query<WithCharValue>("select @ValueNullable as ValueNullable", new WithCharValue { ValueNullable = c }).Single(); obj.ValueNullable.IsEqualTo(test);
}
public void TestInvalidSplitCausesNiceError()
{
try
{
connection.Query<User, User, User>("select 1 A, 2 B, 3 C", (x, y) => x);
}
catch (ArgumentException)
{
// expecting an app exception due to multi mapping being bodged
} try
{
connection.Query<dynamic, dynamic, dynamic>("select 1 A, 2 B, 3 C", (x, y) => x);
}
catch (ArgumentException)
{
// expecting an app exception due to multi mapping being bodged
}
} class Comment
{
public int Id { get; set; }
public string CommentData { get; set; }
} public void TestMultiMapThreeTypesWithGridReader()
{
var createSql = @"
create table #Users (Id int, Name varchar(20))
create table #Posts (Id int, OwnerId int, Content varchar(20))
create table #Comments (Id int, PostId int, CommentData varchar(20))
insert #Users values(99, 'Sam')
insert #Users values(2, 'I am')
insert #Posts values(1, 99, 'Sams Post1')
insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')
insert #Comments values(1, 1, 'Comment 1')";
connection.Execute(createSql);
try
{
var sql = @"SELECT p.* FROM #Posts p
select p.*, u.Id, u.Name + '0' Name, c.Id, c.CommentData from #Posts p
left join #Users u on u.Id = p.OwnerId
left join #Comments c on c.PostId = p.Id
where p.Id = 1
Order by p.Id"; var grid = connection.QueryMultiple(sql); var post1 = grid.Read<Post>().ToList(); var post2 = grid.Read<Post, User, Comment, Post>((post, user, comment) => { post.Owner = user; post.Comment = comment; return post; }).SingleOrDefault(); post2.Comment.Id.IsEqualTo();
post2.Owner.Id.IsEqualTo(); }
finally
{
connection.Execute("drop table #Users drop table #Posts drop table #Comments");
}
} public class DbParams : Dapper.SqlMapper.IDynamicParameters, IEnumerable<IDbDataParameter>
{
private readonly List<IDbDataParameter> parameters = new List<IDbDataParameter>();
public IEnumerator<IDbDataParameter> GetEnumerator() { return parameters.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
public void Add(IDbDataParameter value)
{
parameters.Add(value);
}
void Dapper.SqlMapper.IDynamicParameters.AddParameters(IDbCommand command,
Dapper.SqlMapper.Identity identity)
{
foreach (IDbDataParameter parameter in parameters)
command.Parameters.Add(parameter); }
}
public void TestCustomParameters()
{
var args = new DbParams {
new SqlParameter("foo", ),
new SqlParameter("bar", "abc")
};
var result = connection.Query("select Foo=@foo, Bar=@bar", args).Single();
int foo = result.Foo;
string bar = result.Bar;
foo.IsEqualTo();
bar.IsEqualTo("abc");
} public void TestReadDynamicWithGridReader()
{
var createSql = @"
create table #Users (Id int, Name varchar(20))
create table #Posts (Id int, OwnerId int, Content varchar(20))
insert #Users values(99, 'Sam')
insert #Users values(2, 'I am')
insert #Posts values(1, 99, 'Sams Post1')
insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')";
try
{
connection.Execute(createSql); var sql = @"SELECT * FROM #Users ORDER BY Id
SELECT * FROM #Posts ORDER BY Id DESC"; var grid = connection.QueryMultiple(sql); var users = grid.Read().ToList();
var posts = grid.Read().ToList(); users.Count.IsEqualTo();
posts.Count.IsEqualTo(); ((int)users.First().Id).IsEqualTo();
((int)posts.First().Id).IsEqualTo();
}
finally
{
connection.Execute("drop table #Users drop table #Posts");
}
} public void TestDynamicParamNullSupport()
{
var p = new DynamicParameters(); p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
connection.Execute("select @b = null", p); p.Get<int?>("@b").IsNull();
}
class Foo1
{
#pragma warning disable 0649
public int Id;
#pragma warning restore 0649
public int BarId { get; set; }
}
class Bar1
{
#pragma warning disable 0649
public int BarId;
#pragma warning restore 0649
public string Name { get; set; }
}
public void TestMultiMapperIsNotConfusedWithUnorderedCols()
{
var result = connection.Query<Foo1, Bar1, Tuple<Foo1, Bar1>>("select 1 as Id, 2 as BarId, 3 as BarId, 'a' as Name", (f, b) => Tuple.Create(f, b), splitOn: "BarId").First(); result.Item1.Id.IsEqualTo();
result.Item1.BarId.IsEqualTo();
result.Item2.BarId.IsEqualTo();
result.Item2.Name.IsEqualTo("a");
} #if EXTERNALS
public void TestLinqBinaryToClass()
{
byte[] orig = new byte[];
new Random().NextBytes(orig);
var input = new System.Data.Linq.Binary(orig); var output = connection.Query<WithBinary>("select @input as [Value]", new { input }).First().Value; output.ToArray().IsSequenceEqualTo(orig);
} public void TestLinqBinaryRaw()
{
byte[] orig = new byte[];
new Random().NextBytes(orig);
var input = new System.Data.Linq.Binary(orig); var output = connection.Query<System.Data.Linq.Binary>("select @input as [Value]", new { input }).First(); output.ToArray().IsSequenceEqualTo(orig);
} class WithBinary
{
public System.Data.Linq.Binary Value { get; set; }
}
#endif class WithPrivateConstructor
{
public int Foo { get; set; }
private WithPrivateConstructor() { }
} public void TestWithNonPublicConstructor()
{
var output = connection.Query<WithPrivateConstructor>("select 1 as Foo").First();
output.Foo.IsEqualTo();
} public void TestAppendingAnonClasses()
{
DynamicParameters p = new DynamicParameters();
p.AddDynamicParams(new { A = , B = });
p.AddDynamicParams(new { C = , D = }); var result = connection.Query("select @A a,@B b,@C c,@D d", p).Single(); ((int)result.a).IsEqualTo();
((int)result.b).IsEqualTo();
((int)result.c).IsEqualTo();
((int)result.d).IsEqualTo();
} public void TestAppendingADictionary()
{
var dictionary = new Dictionary<string, object>();
dictionary.Add("A", );
dictionary.Add("B", "two"); DynamicParameters p = new DynamicParameters();
p.AddDynamicParams(dictionary); var result = connection.Query("select @A a, @B b", p).Single(); ((int)result.a).IsEqualTo();
((string)result.b).IsEqualTo("two");
} public void TestAppendingAnExpandoObject()
{
dynamic expando = new System.Dynamic.ExpandoObject();
expando.A = ;
expando.B = "two"; DynamicParameters p = new DynamicParameters();
p.AddDynamicParams(expando); var result = connection.Query("select @A a, @B b", p).Single(); ((int)result.a).IsEqualTo();
((string)result.b).IsEqualTo("two");
} public void TestAppendingAList()
{
DynamicParameters p = new DynamicParameters();
var list = new int[] { , , };
p.AddDynamicParams(new { list }); var result = connection.Query<int>("select * from (select 1 A union all select 2 union all select 3) X where A in @list", p).ToList(); result[].IsEqualTo();
result[].IsEqualTo();
result[].IsEqualTo();
} public void TestAppendingAListAsDictionary()
{
DynamicParameters p = new DynamicParameters();
var list = new int[] { , , };
var args = new Dictionary<string, object>();
args.Add("ids", list);
p.AddDynamicParams(args); var result = connection.Query<int>("select * from (select 1 A union all select 2 union all select 3) X where A in @ids", p).ToList(); result[].IsEqualTo();
result[].IsEqualTo();
result[].IsEqualTo();
} public void TestAppendingAListByName()
{
DynamicParameters p = new DynamicParameters();
var list = new int[] { , , };
p.Add("ids", list); var result = connection.Query<int>("select * from (select 1 A union all select 2 union all select 3) X where A in @ids", p).ToList(); result[].IsEqualTo();
result[].IsEqualTo();
result[].IsEqualTo();
} public void TestUniqueIdentifier()
{
var guid = Guid.NewGuid();
var result = connection.Query<Guid>("declare @foo uniqueidentifier set @foo = @guid select @foo", new { guid }).Single();
result.IsEqualTo(guid);
}
public void TestNullableUniqueIdentifierNonNull()
{
Guid? guid = Guid.NewGuid();
var result = connection.Query<Guid?>("declare @foo uniqueidentifier set @foo = @guid select @foo", new { guid }).Single();
result.IsEqualTo(guid);
}
public void TestNullableUniqueIdentifierNull()
{
Guid? guid = null;
var result = connection.Query<Guid?>("declare @foo uniqueidentifier set @foo = @guid select @foo", new { guid }).Single();
result.IsEqualTo(guid);
} public void WorkDespiteHavingWrongStructColumnTypes()
{
var hazInt = connection.Query<CanHazInt>("select cast(1 as bigint) Value").Single();
hazInt.Value.Equals();
} public void TestProcWithOutParameter()
{
connection.Execute(
@"CREATE PROCEDURE #TestProcWithOutParameter
@ID int output,
@Foo varchar(100),
@Bar int
AS
SET @ID = @Bar + LEN(@Foo)");
var obj = new
{
ID = ,
Foo = "abc",
Bar =
};
var args = new DynamicParameters(obj);
args.Add("ID", , direction: ParameterDirection.Output);
connection.Execute("#TestProcWithOutParameter", args, commandType: CommandType.StoredProcedure);
args.Get<int>("ID").IsEqualTo();
}
public void TestProcWithOutAndReturnParameter()
{
connection.Execute(
@"CREATE PROCEDURE #TestProcWithOutAndReturnParameter
@ID int output,
@Foo varchar(100),
@Bar int
AS
SET @ID = @Bar + LEN(@Foo)
RETURN 42");
var obj = new
{
ID = ,
Foo = "abc",
Bar =
};
var args = new DynamicParameters(obj);
args.Add("ID", , direction: ParameterDirection.Output);
args.Add("result", , direction: ParameterDirection.ReturnValue);
connection.Execute("#TestProcWithOutAndReturnParameter", args, commandType: CommandType.StoredProcedure);
args.Get<int>("ID").IsEqualTo();
args.Get<int>("result").IsEqualTo();
}
struct CanHazInt
{
public int Value { get; set; }
}
public void TestInt16Usage()
{
connection.Query<short>("select cast(42 as smallint)").Single().IsEqualTo((short));
connection.Query<short?>("select cast(42 as smallint)").Single().IsEqualTo((short?));
connection.Query<short?>("select cast(null as smallint)").Single().IsEqualTo((short?)null); connection.Query<ShortEnum>("select cast(42 as smallint)").Single().IsEqualTo((ShortEnum));
connection.Query<ShortEnum?>("select cast(42 as smallint)").Single().IsEqualTo((ShortEnum?));
connection.Query<ShortEnum?>("select cast(null as smallint)").Single().IsEqualTo((ShortEnum?)null); var row =
connection.Query<WithInt16Values>(
"select cast(1 as smallint) as NonNullableInt16, cast(2 as smallint) as NullableInt16, cast(3 as smallint) as NonNullableInt16Enum, cast(4 as smallint) as NullableInt16Enum")
.Single();
row.NonNullableInt16.IsEqualTo((short));
row.NullableInt16.IsEqualTo((short));
row.NonNullableInt16Enum.IsEqualTo(ShortEnum.Three);
row.NullableInt16Enum.IsEqualTo(ShortEnum.Four); row =
connection.Query<WithInt16Values>(
"select cast(5 as smallint) as NonNullableInt16, cast(null as smallint) as NullableInt16, cast(6 as smallint) as NonNullableInt16Enum, cast(null as smallint) as NullableInt16Enum")
.Single();
row.NonNullableInt16.IsEqualTo((short));
row.NullableInt16.IsEqualTo((short?)null);
row.NonNullableInt16Enum.IsEqualTo(ShortEnum.Six);
row.NullableInt16Enum.IsEqualTo((ShortEnum?)null);
}
public void TestInt32Usage()
{
connection.Query<int>("select cast(42 as int)").Single().IsEqualTo((int));
connection.Query<int?>("select cast(42 as int)").Single().IsEqualTo((int?));
connection.Query<int?>("select cast(null as int)").Single().IsEqualTo((int?)null); connection.Query<IntEnum>("select cast(42 as int)").Single().IsEqualTo((IntEnum));
connection.Query<IntEnum?>("select cast(42 as int)").Single().IsEqualTo((IntEnum?));
connection.Query<IntEnum?>("select cast(null as int)").Single().IsEqualTo((IntEnum?)null); var row =
connection.Query<WithInt32Values>(
"select cast(1 as int) as NonNullableInt32, cast(2 as int) as NullableInt32, cast(3 as int) as NonNullableInt32Enum, cast(4 as int) as NullableInt32Enum")
.Single();
row.NonNullableInt32.IsEqualTo((int));
row.NullableInt32.IsEqualTo((int));
row.NonNullableInt32Enum.IsEqualTo(IntEnum.Three);
row.NullableInt32Enum.IsEqualTo(IntEnum.Four); row =
connection.Query<WithInt32Values>(
"select cast(5 as int) as NonNullableInt32, cast(null as int) as NullableInt32, cast(6 as int) as NonNullableInt32Enum, cast(null as int) as NullableInt32Enum")
.Single();
row.NonNullableInt32.IsEqualTo((int));
row.NullableInt32.IsEqualTo((int?)null);
row.NonNullableInt32Enum.IsEqualTo(IntEnum.Six);
row.NullableInt32Enum.IsEqualTo((IntEnum?)null);
} public class WithInt16Values
{
public short NonNullableInt16 { get; set; }
public short? NullableInt16 { get; set; }
public ShortEnum NonNullableInt16Enum { get; set; }
public ShortEnum? NullableInt16Enum { get; set; }
}
public enum ShortEnum : short
{
Zero = , One = , Two = , Three = , Four = , Five = , Six =
}
public class WithInt32Values
{
public int NonNullableInt32 { get; set; }
public int? NullableInt32 { get; set; }
public IntEnum NonNullableInt32Enum { get; set; }
public IntEnum? NullableInt32Enum { get; set; }
}
public enum IntEnum : int
{
Zero = , One = , Two = , Three = , Four = , Five = , Six =
} public void TestTransactionCommit()
{
try
{
connection.Execute("create table #TransactionTest ([ID] int, [Value] varchar(32));"); using (var transaction = connection.BeginTransaction())
{
connection.Execute("insert into #TransactionTest ([ID], [Value]) values (1, 'ABC');", transaction: transaction); transaction.Commit();
} connection.Query<int>("select count(*) from #TransactionTest;").Single().IsEqualTo();
}
finally
{
connection.Execute("drop table #TransactionTest;");
}
} public void TestTransactionRollback()
{
connection.Execute("create table #TransactionTest ([ID] int, [Value] varchar(32));"); try
{
using (var transaction = connection.BeginTransaction())
{
connection.Execute("insert into #TransactionTest ([ID], [Value]) values (1, 'ABC');", transaction: transaction); transaction.Rollback();
} connection.Query<int>("select count(*) from #TransactionTest;").Single().IsEqualTo();
}
finally
{
connection.Execute("drop table #TransactionTest;");
}
} public void TestCommandWithInheritedTransaction()
{
connection.Execute("create table #TransactionTest ([ID] int, [Value] varchar(32));"); try
{
using (var transaction = connection.BeginTransaction())
{
var transactedConnection = new TransactedConnection(connection, transaction); transactedConnection.Execute("insert into #TransactionTest ([ID], [Value]) values (1, 'ABC');"); transaction.Rollback();
} connection.Query<int>("select count(*) from #TransactionTest;").Single().IsEqualTo();
}
finally
{
connection.Execute("drop table #TransactionTest;");
}
} public void TestReaderWhenResultsChange()
{
try
{ connection.Execute("create table #ResultsChange (X int);create table #ResultsChange2 (Y int);insert #ResultsChange (X) values(1);insert #ResultsChange2 (Y) values(1);"); var obj1 = connection.Query<ResultsChangeType>("select * from #ResultsChange").Single();
obj1.X.IsEqualTo();
obj1.Y.IsEqualTo();
obj1.Z.IsEqualTo(); var obj2 = connection.Query<ResultsChangeType>("select * from #ResultsChange rc inner join #ResultsChange2 rc2 on rc2.Y=rc.X").Single();
obj2.X.IsEqualTo();
obj2.Y.IsEqualTo();
obj2.Z.IsEqualTo(); connection.Execute("alter table #ResultsChange add Z int null");
connection.Execute("update #ResultsChange set Z = 2"); var obj3 = connection.Query<ResultsChangeType>("select * from #ResultsChange").Single();
obj3.X.IsEqualTo();
obj3.Y.IsEqualTo();
obj3.Z.IsEqualTo(); var obj4 = connection.Query<ResultsChangeType>("select * from #ResultsChange rc inner join #ResultsChange2 rc2 on rc2.Y=rc.X").Single();
obj4.X.IsEqualTo();
obj4.Y.IsEqualTo();
obj4.Z.IsEqualTo();
}
finally
{
connection.Execute("drop table #ResultsChange;drop table #ResultsChange2;");
}
}
class ResultsChangeType
{
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
} public void TestCustomTypeMap()
{
// default mapping
var item = connection.Query<TypeWithMapping>("Select 'AVal' as A, 'BVal' as B").Single();
item.A.IsEqualTo("AVal");
item.B.IsEqualTo("BVal"); // custom mapping
var map = new CustomPropertyTypeMap(typeof(TypeWithMapping),
(type, columnName) => type.GetProperties().Where(prop => GetDescriptionFromAttribute(prop) == columnName).FirstOrDefault());
Dapper.SqlMapper.SetTypeMap(typeof(TypeWithMapping), map); item = connection.Query<TypeWithMapping>("Select 'AVal' as A, 'BVal' as B").Single();
item.A.IsEqualTo("BVal");
item.B.IsEqualTo("AVal"); // reset to default
Dapper.SqlMapper.SetTypeMap(typeof(TypeWithMapping), null);
item = connection.Query<TypeWithMapping>("Select 'AVal' as A, 'BVal' as B").Single();
item.A.IsEqualTo("AVal");
item.B.IsEqualTo("BVal");
}
static string GetDescriptionFromAttribute(MemberInfo member)
{
if (member == null) return null;
#if DNXCORE50
var data = member.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(DescriptionAttribute));
return data == null ? null : (string)data.ConstructorArguments.Single().Value;
#else
var attrib = (DescriptionAttribute)Attribute.GetCustomAttribute(member, typeof(DescriptionAttribute), false);
return attrib == null ? null : attrib.Description;
#endif
}
public class TypeWithMapping
{
[Description("B")]
public string A { get; set; } [Description("A")]
public string B { get; set; }
} public class WrongTypes
{
public int A { get; set; }
public double B { get; set; }
public long C { get; set; }
public bool D { get; set; }
} public void TestWrongTypes_WithRightTypes()
{
var item = connection.Query<WrongTypes>("select 1 as A, cast(2.0 as float) as B, cast(3 as bigint) as C, cast(1 as bit) as D").Single();
item.A.Equals();
item.B.Equals(2.0);
item.C.Equals(3L);
item.D.Equals(true);
} public void TestWrongTypes_WithWrongTypes()
{
var item = connection.Query<WrongTypes>("select cast(1.0 as float) as A, 2 as B, 3 as C, cast(1 as bigint) as D").Single();
item.A.Equals();
item.B.Equals(2.0);
item.C.Equals(3L);
item.D.Equals(true);
} public void Test_AddDynamicParametersRepeatedShouldWork()
{
var args = new DynamicParameters();
args.AddDynamicParams(new { Foo = });
args.AddDynamicParams(new { Foo = });
int i = connection.Query<int>("select @Foo", args).Single();
i.IsEqualTo();
} public class ParameterWithIndexer
{
public int A { get; set; }
public virtual string this[string columnName]
{
get { return null; }
set { }
}
} public void TestParameterWithIndexer()
{
connection.Execute(@"create proc #TestProcWithIndexer
@A int
as
begin
select @A
end");
var item = connection.Query<int>("#TestProcWithIndexer", new ParameterWithIndexer(), commandType: CommandType.StoredProcedure).Single();
} public class MultipleParametersWithIndexerDeclaringType
{
public object this[object field] { get { return null; } set { } }
public object this[object field, int index] { get { return null; } set { } }
public int B { get; set; }
} public class MultipleParametersWithIndexer : MultipleParametersWithIndexerDeclaringType
{
public int A { get; set; }
} public void TestMultipleParametersWithIndexer()
{
var order = connection.Query<MultipleParametersWithIndexer>("select 1 A,2 B").First(); order.A.IsEqualTo();
order.B.IsEqualTo();
} public void Issue_40_AutomaticBoolConversion()
{
var user = connection.Query<Issue40_User>("select UserId=1,Email='abc',Password='changeme',Active=cast(1 as tinyint)").Single();
user.Active.IsTrue();
user.UserID.IsEqualTo();
user.Email.IsEqualTo("abc");
user.Password.IsEqualTo("changeme");
} public class Issue40_User
{
public Issue40_User()
{
Email = Password = String.Empty;
}
public int UserID { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public bool Active { get; set; }
} SqlConnection GetClosedConnection()
{
var conn = new SqlConnection(connection.ConnectionString);
if (conn.State != ConnectionState.Closed) throw new InvalidOperationException("should be closed!");
return conn;
}
public void ExecuteFromClosed()
{
using (var conn = GetClosedConnection())
{
conn.Execute("-- nop");
conn.State.IsEqualTo(ConnectionState.Closed);
}
}
class Multi1
{
public int Id { get; set; }
}
class Multi2
{
public int Id { get; set; }
}
public void QueryMultimapFromClosed()
{
using (var conn = GetClosedConnection())
{
conn.State.IsEqualTo(ConnectionState.Closed);
var i = conn.Query<Multi1, Multi2, int>("select 2 as [Id], 3 as [Id]", (x, y) => x.Id + y.Id).Single();
conn.State.IsEqualTo(ConnectionState.Closed);
i.IsEqualTo();
}
}
public void QueryMultiple2FromClosed()
{
using (var conn = GetClosedConnection())
{
conn.State.IsEqualTo(ConnectionState.Closed);
using (var multi = conn.QueryMultiple("select 1 select 2 select 3"))
{
multi.Read<int>().Single().IsEqualTo();
multi.Read<int>().Single().IsEqualTo();
// not reading 3 is intentional here
}
conn.State.IsEqualTo(ConnectionState.Closed);
}
}
public void ExecuteInvalidFromClosed()
{
using (var conn = GetClosedConnection())
{
try
{
conn.Execute("nop");
false.IsEqualTo(true); // shouldn't have got here
}
catch
{
conn.State.IsEqualTo(ConnectionState.Closed);
}
}
}
public void QueryFromClosed()
{
using (var conn = GetClosedConnection())
{
var i = conn.Query<int>("select 1").Single();
conn.State.IsEqualTo(ConnectionState.Closed);
i.IsEqualTo();
}
}
public void QueryInvalidFromClosed()
{
using (var conn = GetClosedConnection())
{
try
{
conn.Query<int>("select gibberish").Single();
false.IsEqualTo(true); // shouldn't have got here
}
catch
{
conn.State.IsEqualTo(ConnectionState.Closed);
}
}
}
public void QueryMultipleFromClosed()
{
using (var conn = GetClosedConnection())
{
using (var multi = conn.QueryMultiple("select 1; select 'abc';"))
{
multi.Read<int>().Single().IsEqualTo();
multi.Read<string>().Single().IsEqualTo("abc");
}
conn.State.IsEqualTo(ConnectionState.Closed);
}
}
public void QueryMultipleInvalidFromClosed()
{
using (var conn = GetClosedConnection())
{
try
{
conn.QueryMultiple("select gibberish");
false.IsEqualTo(true); // shouldn't have got here
}
catch
{
conn.State.IsEqualTo(ConnectionState.Closed);
}
}
} public void TestMultiSelectWithSomeEmptyGrids()
{
using (var reader = connection.QueryMultiple("select 1; select 2 where 1 = 0; select 3 where 1 = 0; select 4;"))
{
var one = reader.Read<int>().ToArray();
var two = reader.Read<int>().ToArray();
var three = reader.Read<int>().ToArray();
var four = reader.Read<int>().ToArray();
try
{ // only returned four grids; expect a fifth read to fail
reader.Read<int>();
throw new InvalidOperationException("this should not have worked!");
}
catch (ObjectDisposedException ex)
{ // expected; success
ex.Message.IsEqualTo("The reader has been disposed; this can happen after all data has been consumed\r\nObject name: 'Dapper.SqlMapper+GridReader'.");
} one.Length.IsEqualTo();
one[].IsEqualTo();
two.Length.IsEqualTo();
three.Length.IsEqualTo();
four.Length.IsEqualTo();
four[].IsEqualTo();
}
} public void TestDynamicMutation()
{
var obj = connection.Query("select 1 as [a], 2 as [b], 3 as [c]").Single();
((int)obj.a).IsEqualTo();
IDictionary<string, object> dict = obj;
Assert.Equals(, dict.Count);
Assert.IsTrue(dict.Remove("a"));
Assert.IsFalse(dict.Remove("d"));
Assert.Equals(, dict.Count);
dict.Add("d", );
Assert.Equals(, dict.Count);
Assert.Equals("b,c,d", string.Join(",", dict.Keys.OrderBy(x => x)));
Assert.Equals("2,3,4", string.Join(",", dict.OrderBy(x => x.Key).Select(x => x.Value))); Assert.Equals(, (int)obj.b);
Assert.Equals(, (int)obj.c);
Assert.Equals(, (int)obj.d);
try
{
((int)obj.a).IsEqualTo();
throw new InvalidOperationException("should have thrown");
}
catch (RuntimeBinderException)
{
// pass
}
} public void TestIssue131()
{
var results = connection.Query<dynamic, int, dynamic>(
"SELECT 1 Id, 'Mr' Title, 'John' Surname, 4 AddressCount",
(person, addressCount) =>
{
return person;
},
splitOn: "AddressCount"
).FirstOrDefault(); var asDict = (IDictionary<string, object>)results; asDict.ContainsKey("Id").IsEqualTo(true);
asDict.ContainsKey("Title").IsEqualTo(true);
asDict.ContainsKey("Surname").IsEqualTo(true);
asDict.ContainsKey("AddressCount").IsEqualTo(false);
}
// see http://stackoverflow.com/questions/16955357/issue-about-dapper
public void TestSplitWithMissingMembers()
{
var result = connection.Query<Topic, Profile, Topic>(
@"select 123 as ID, 'abc' as Title,
cast('01 Feb 2013' as datetime) as CreateDate,
'ghi' as Name, 'def' as Phone",
(T, P) => { T.Author = P; return T; },
null, null, true, "ID,Name").Single(); result.ID.Equals();
result.Title.Equals("abc");
result.CreateDate.Equals(new DateTime(, , ));
result.Name.IsNull();
result.Content.IsNull(); result.Author.Phone.Equals("def");
result.Author.Name.Equals("ghi");
result.Author.ID.Equals();
result.Author.Address.IsNull();
}
public class Profile
{
public int ID { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
//public ExtraInfo Extra { get; set; }
} public class Topic
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime CreateDate { get; set; }
public string Content { get; set; }
public int UID { get; set; }
public int TestColum { get; set; }
public string Name { get; set; }
public Profile Author { get; set; }
//public Attachment Attach { get; set; }
} // see http://stackoverflow.com/questions/13127886/dapper-returns-null-for-singleordefaultdatediff
public void TestNullFromInt_NoRows()
{
var result = connection.Query<int>( // case with rows
"select DATEDIFF(day, GETUTCDATE(), @date)", new { date = DateTime.UtcNow.AddDays() })
.SingleOrDefault();
result.IsEqualTo(); result = connection.Query<int>( // case without rows
"select DATEDIFF(day, GETUTCDATE(), @date) where 1 = 0", new { date = DateTime.UtcNow.AddDays() })
.SingleOrDefault();
result.IsEqualTo(); // zero rows; default of int over zero rows is zero } public void TestChangingDefaultStringTypeMappingToAnsiString()
{
var sql = "SELECT SQL_VARIANT_PROPERTY(CONVERT(sql_variant, @testParam),'BaseType') AS BaseType";
var param = new { testParam = "TestString" }; var result01 = connection.Query<string>(sql, param).FirstOrDefault();
result01.IsEqualTo("nvarchar"); Dapper.SqlMapper.PurgeQueryCache(); Dapper.SqlMapper.AddTypeMap(typeof(string), DbType.AnsiString); // Change Default String Handling to AnsiString
var result02 = connection.Query<string>(sql, param).FirstOrDefault();
result02.IsEqualTo("varchar"); Dapper.SqlMapper.PurgeQueryCache();
Dapper.SqlMapper.AddTypeMap(typeof(string), DbType.String); // Restore Default to Unicode String
}
#if DNXCORE50
class TransactedConnection : IDbConnection
{
IDbConnection _conn;
IDbTransaction _tran; public TransactedConnection(IDbConnection conn, IDbTransaction tran)
{
_conn = conn;
_tran = tran;
} public override string ConnectionString { get { return _conn.ConnectionString; } set { _conn.ConnectionString = value; } }
public override int ConnectionTimeout { get { return _conn.ConnectionTimeout; } }
public override string Database { get { return _conn.Database; } }
public override ConnectionState State { get { return _conn.State; } } protected override IDbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
{
return _tran;
} public override void ChangeDatabase(string databaseName)
{
_conn.ChangeDatabase(databaseName);
}
public override string DataSource
{
get
{
return _conn.DataSource;
}
}
public override string ServerVersion
{
get
{
return _conn.ServerVersion;
}
}
public override void Close()
{
_conn.Close();
}
protected override IDbCommand CreateDbCommand()
{
// The command inherits the "current" transaction.
var command = _conn.CreateCommand();
command.Transaction = _tran;
return command;
} protected override void Dispose(bool disposing)
{
if(disposing) _conn.Dispose();
base.Dispose(disposing);
} public override void Open()
{
_conn.Open();
}
}
#else
class TransactedConnection : IDbConnection
{
IDbConnection _conn;
IDbTransaction _tran; public TransactedConnection(IDbConnection conn, IDbTransaction tran)
{
_conn = conn;
_tran = tran;
} public string ConnectionString { get { return _conn.ConnectionString; } set { _conn.ConnectionString = value; } }
public int ConnectionTimeout { get { return _conn.ConnectionTimeout; } }
public string Database { get { return _conn.Database; } }
public ConnectionState State { get { return _conn.State; } } public IDbTransaction BeginTransaction(IsolationLevel il)
{
throw new NotImplementedException();
} public IDbTransaction BeginTransaction()
{
return _tran;
} public void ChangeDatabase(string databaseName)
{
_conn.ChangeDatabase(databaseName);
} public void Close()
{
_conn.Close();
} public IDbCommand CreateCommand()
{
// The command inherits the "current" transaction.
var command = _conn.CreateCommand();
command.Transaction = _tran;
return command;
} public void Dispose()
{
_conn.Dispose();
} public void Open()
{
_conn.Open();
}
}
#endif
public void TestDapperTableMetadataRetrieval()
{
// Test for a bug found in CS 51509960 where the following sequence would result in an InvalidOperationException being
// thrown due to an attempt to access a disposed of DataReader:
//
// - Perform a dynamic query that yields no results
// - Add data to the source of that query
// - Perform a the same query again
connection.Execute("CREATE TABLE #sut (value varchar(10) NOT NULL PRIMARY KEY)");
connection.Query("SELECT value FROM #sut").IsSequenceEqualTo(Enumerable.Empty<dynamic>()); connection.Execute("INSERT INTO #sut (value) VALUES ('test')").IsEqualTo();
var result = connection.Query("SELECT value FROM #sut"); var first = result.First();
((string)first.value).IsEqualTo("test");
} public void TestIssue17648290()
{
var p = new DynamicParameters();
int code = , getMessageControlId = ;
p.Add("@Code", code);
p.Add("@MessageControlID", getMessageControlId);
p.Add("@SuccessCode", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("@ErrorDescription", dbType: DbType.String, direction: ParameterDirection.Output, size: );
connection.Execute(@"CREATE PROCEDURE #up_MessageProcessed_get
@Code varchar(10),
@MessageControlID varchar(22),
@SuccessCode int OUTPUT,
@ErrorDescription varchar(255) OUTPUT
AS
BEGIN
Select 2 as MessageProcessID, 38349348 as StartNum, 3874900 as EndNum, GETDATE() as StartDate, GETDATE() as EndDate
SET @SuccessCode = 0
SET @ErrorDescription = 'Completed successfully'
END");
var result = connection.Query(sql: "#up_MessageProcessed_get", param: p, commandType: CommandType.StoredProcedure);
var row = result.Single();
((int)row.MessageProcessID).IsEqualTo();
((int)row.StartNum).IsEqualTo();
((int)row.EndNum).IsEqualTo();
DateTime startDate = row.StartDate, endDate = row.EndDate;
p.Get<int>("SuccessCode").IsEqualTo();
p.Get<string>("ErrorDescription").IsEqualTo("Completed successfully");
} public void TestDoubleDecimalConversions_SO18228523_RightWay()
{
var row = connection.Query<HasDoubleDecimal>(
"select cast(1 as float) as A, cast(2 as float) as B, cast(3 as decimal) as C, cast(4 as decimal) as D").Single();
row.A.Equals(1.0);
row.B.Equals(2.0);
row.C.Equals(3.0M);
row.D.Equals(4.0M);
}
public void TestDoubleDecimalConversions_SO18228523_WrongWay()
{
var row = connection.Query<HasDoubleDecimal>(
"select cast(1 as decimal) as A, cast(2 as decimal) as B, cast(3 as float) as C, cast(4 as float) as D").Single();
row.A.Equals(1.0);
row.B.Equals(2.0);
row.C.Equals(3.0M);
row.D.Equals(4.0M);
}
public void TestDoubleDecimalConversions_SO18228523_Nulls()
{
var row = connection.Query<HasDoubleDecimal>(
"select cast(null as decimal) as A, cast(null as decimal) as B, cast(null as float) as C, cast(null as float) as D").Single();
row.A.Equals(0.0);
row.B.IsNull();
row.C.Equals(0.0M);
row.D.IsNull();
}
private static CultureInfo ActiveCulture
{
#if DNXCORE50
get { return CultureInfo.CurrentCulture; }
set { CultureInfo.CurrentCulture = value; }
#else
get { return Thread.CurrentThread.CurrentCulture; }
set { Thread.CurrentThread.CurrentCulture = value; }
#endif
}
public void TestParameterInclusionNotSensitiveToCurrentCulture()
{
// note this might fail if your database server is case-sensitive
CultureInfo current = ActiveCulture;
try
{
ActiveCulture = new CultureInfo("tr-TR"); connection.Query<int>("select @pid", new { PId = }).Single();
}
finally
{
ActiveCulture = current;
}
}
public void LiteralReplacement()
{
connection.Execute("create table #literal1 (id int not null, foo int not null)");
connection.Execute("insert #literal1 (id,foo) values ({=id}, @foo)", new { id = , foo = });
var rows = new[] { new { id = , foo = }, new { id = , foo = } };
connection.Execute("insert #literal1 (id,foo) values ({=id}, @foo)", rows);
var count = connection.Query<int>("select count(1) from #literal1 where id={=foo}", new { foo = }).Single();
count.IsEqualTo();
int sum = connection.Query<int>("select sum(id) + sum(foo) from #literal1").Single();
sum.IsEqualTo( + + + + + );
}
public void LiteralReplacementDynamic()
{
var args = new DynamicParameters();
args.Add("id", );
connection.Execute("create table #literal2 (id int not null)");
connection.Execute("insert #literal2 (id) values ({=id})", args); args = new DynamicParameters();
args.Add("foo", );
var count = connection.Query<int>("select count(1) from #literal2 where id={=foo}", args).Single();
count.IsEqualTo();
} enum AnEnum
{
A = ,
B =
}
enum AnotherEnum : byte
{
A = ,
B =
} #if DNXCORE50
[FrameworkFail("https://github.com/dotnet/corefx/issues/1613")]
#endif
public void AdoNetEnumValue()
{
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = "select @foo";
cmd.Parameters.AddWithValue("@foo", AnEnum.B);
object value = cmd.ExecuteScalar();
AnEnum val = (AnEnum)value;
val.IsEqualTo(AnEnum.B);
}
} public void LiteralReplacementEnumAndString()
{
var args = new { x = AnEnum.B, y = 123.45M, z = AnotherEnum.A };
var row = connection.Query("select {=x} as x,{=y} as y,cast({=z} as tinyint) as z", args).Single();
AnEnum x = (AnEnum)(int)row.x;
decimal y = row.y;
AnotherEnum z = (AnotherEnum)(byte)row.z;
x.Equals(AnEnum.B);
y.Equals(123.45M);
z.Equals(AnotherEnum.A);
} public void LiteralReplacementDynamicEnumAndString()
{
var args = new DynamicParameters();
args.Add("x", AnEnum.B);
args.Add("y", 123.45M);
args.Add("z", AnotherEnum.A);
var row = connection.Query("select {=x} as x,{=y} as y,cast({=z} as tinyint) as z", args).Single();
AnEnum x = (AnEnum)(int)row.x;
decimal y = row.y;
AnotherEnum z = (AnotherEnum)(byte)row.z;
x.Equals(AnEnum.B);
y.Equals(123.45M);
z.Equals(AnotherEnum.A);
} public void LiteralReplacementBoolean()
{
var row = connection.Query<int?>("select 42 where 1 = {=val}", new { val = true }).SingleOrDefault();
row.IsNotNull();
row.IsEqualTo();
row = connection.Query<int?>("select 42 where 1 = {=val}", new { val = false }).SingleOrDefault();
row.IsNull();
}
public void LiteralReplacementWithIn()
{
var data = connection.Query<MyRow>("select @x where 1 in @ids and 1 ={=a}",
new { x = , ids = new[] { , , }, a = }).ToList();
} class MyRow
{
public int x { get; set; }
} public void LiteralIn()
{
connection.Execute("create table #literalin(id int not null);");
connection.Execute("insert #literalin (id) values (@id)", new[] {
new { id = },
new { id = },
new { id = },
});
var count = connection.Query<int>("select count(1) from #literalin where id in {=ids}",
new { ids = new[] { , , } }).Single();
count.IsEqualTo();
} public void ParameterizedInWithOptimizeHint()
{
const string sql = @"
select count(1)
from(
select 1 as x
union all select 2
union all select 5) y
where y.x in @vals
option (optimize for (@vals unKnoWn))";
int count = connection.Query<int>(sql, new { vals = new[] { , , , } }).Single();
count.IsEqualTo(); count = connection.Query<int>(sql, new { vals = new[] { } }).Single();
count.IsEqualTo(); count = connection.Query<int>(sql, new { vals = new int[] }).Single();
count.IsEqualTo();
} public void TestProcedureWithTimeParameter()
{
var p = new DynamicParameters();
p.Add("a", TimeSpan.FromHours(), dbType: DbType.Time); connection.Execute(@"CREATE PROCEDURE #TestProcWithTimeParameter
@a TIME
AS
BEGIN
SELECT @a
END");
connection.Query<TimeSpan>("#TestProcWithTimeParameter", p, commandType: CommandType.StoredProcedure).First().IsEqualTo(new TimeSpan(, , ));
} public void DbString()
{
var a = connection.Query<int>("select datalength(@x)",
new { x = new DbString { Value = "abc", IsAnsi = true } }).Single();
var b = connection.Query<int>("select datalength(@x)",
new { x = new DbString { Value = "abc", IsAnsi = false } }).Single();
a.IsEqualTo();
b.IsEqualTo();
} class HasInt32
{
public int Value { get; set; }
}
// http://stackoverflow.com/q/23696254/23354
public void DownwardIntegerConversion()
{
const string sql = "select cast(42 as bigint) as Value";
int i = connection.Query<HasInt32>(sql).Single().Value;
Assert.IsEqualTo(, i); i = connection.Query<int>(sql).Single();
Assert.IsEqualTo(, i);
} class HasDoubleDecimal
{
public double A { get; set; }
public double? B { get; set; }
public decimal C { get; set; }
public decimal? D { get; set; }
}
#if EXTERNALS
public void DataTableParameters()
{
try { connection.Execute("drop proc #DataTableParameters"); }
catch { }
try { connection.Execute("drop table #DataTableParameters"); }
catch { }
try { connection.Execute("drop type MyTVPType"); }
catch { }
connection.Execute("create type MyTVPType as table (id int)");
connection.Execute("create proc #DataTableParameters @ids MyTVPType readonly as select count(1) from @ids"); var table = new DataTable { Columns = { { "id", typeof(int) } }, Rows = { { }, { }, { } } }; int count = connection.Query<int>("#DataTableParameters", new { ids = table.AsTableValuedParameter() }, commandType: CommandType.StoredProcedure).First();
count.IsEqualTo(); count = connection.Query<int>("select count(1) from @ids", new { ids = table.AsTableValuedParameter("MyTVPType") }).First();
count.IsEqualTo(); try
{
connection.Query<int>("select count(1) from @ids", new { ids = table.AsTableValuedParameter() }).First();
throw new InvalidOperationException();
}
catch (Exception ex)
{
ex.Message.Equals("The table type parameter 'ids' must have a valid type name.");
}
} public void SO29533765_DataTableParametersViaDynamicParameters()
{
try { connection.Execute("drop proc #DataTableParameters"); } catch { }
try { connection.Execute("drop table #DataTableParameters"); } catch { }
try { connection.Execute("drop type MyTVPType"); } catch { }
connection.Execute("create type MyTVPType as table (id int)");
connection.Execute("create proc #DataTableParameters @ids MyTVPType readonly as select count(1) from @ids"); var table = new DataTable { TableName="MyTVPType", Columns = { { "id", typeof(int) } }, Rows = { { }, { }, { } } };
table.SetTypeName(table.TableName); // per SO29533765
IDictionary<string, object> args = new Dictionary<string, object>();
args.Add("ids", table);
int count = connection.Query<int>("#DataTableParameters", args, commandType: CommandType.StoredProcedure).First();
count.IsEqualTo(); count = connection.Query<int>("select count(1) from @ids", args).First();
count.IsEqualTo();
}
public void SO26468710_InWithTVPs()
{
// this is just to make it re-runnable; normally you only do this once
try { connection.Execute("drop type MyIdList"); }
catch { }
connection.Execute("create type MyIdList as table(id int);"); DataTable ids = new DataTable
{
Columns = { { "id", typeof(int) } },
Rows = { { }, { }, { } }
};
ids.SetTypeName("MyIdList");
int sum = connection.Query<int>(@"
declare @tmp table(id int not null);
insert @tmp (id) values(1), (2), (3), (4), (5), (6), (7);
select * from @tmp t inner join @ids i on i.id = t.id", new { ids }).Sum();
sum.IsEqualTo();
}
public void DataTableParametersWithExtendedProperty()
{
try { connection.Execute("drop proc #DataTableParameters"); }
catch { }
try { connection.Execute("drop table #DataTableParameters"); }
catch { }
try { connection.Execute("drop type MyTVPType"); }
catch { }
connection.Execute("create type MyTVPType as table (id int)");
connection.Execute("create proc #DataTableParameters @ids MyTVPType readonly as select count(1) from @ids"); var table = new DataTable { Columns = { { "id", typeof(int) } }, Rows = { { }, { }, { } } };
table.SetTypeName("MyTVPType"); // <== extended metadata
int count = connection.Query<int>("#DataTableParameters", new { ids = table }, commandType: CommandType.StoredProcedure).First();
count.IsEqualTo(); count = connection.Query<int>("select count(1) from @ids", new { ids = table }).First();
count.IsEqualTo(); try
{
connection.Query<int>("select count(1) from @ids", new { ids = table }).First();
throw new InvalidOperationException();
}
catch (Exception ex)
{
ex.Message.Equals("The table type parameter 'ids' must have a valid type name.");
}
} public void SupportInit()
{
var obj = connection.Query<WithInit>("select 'abc' as Value").Single();
obj.Value.Equals("abc");
obj.Flags.Equals();
}
#endif
public void GuidIn_SO_24177902()
{
// invent and populate
Guid a = Guid.NewGuid(), b = Guid.NewGuid(), c = Guid.NewGuid(), d = Guid.NewGuid();
connection.Execute("create table #foo (i int, g uniqueidentifier)");
connection.Execute("insert #foo(i,g) values(@i,@g)",
new[] { new { i = , g = a }, new { i = , g = b },
new { i = , g = c },new { i = , g = d }}); // check that rows 2&3 yield guids b&c
var guids = connection.Query<Guid>("select g from #foo where i in (2,3)").ToArray();
guids.Length.Equals();
guids.Contains(a).Equals(false);
guids.Contains(b).Equals(true);
guids.Contains(c).Equals(true);
guids.Contains(d).Equals(false); // in query on the guids
var rows = connection.Query("select * from #foo where g in @guids order by i", new { guids })
.Select(row => new { i = (int)row.i, g = (Guid)row.g }).ToArray();
rows.Length.Equals();
rows[].i.Equals();
rows[].g.Equals(b);
rows[].i.Equals();
rows[].g.Equals(c);
}
#if EXTERNALS
class HazGeo
{
public int Id { get; set; }
public DbGeography Geo { get; set; }
public DbGeometry Geometry { get; set; }
}
class HazSqlGeo
{
public int Id { get; set; }
public SqlGeography Geo { get; set; }
public SqlGeometry Geometry { get; set; }
}
public void DBGeography_SO24405645_SO24402424()
{
Dapper.EntityFramework.Handlers.Register(); connection.Execute("create table #Geo (id int, geo geography, geometry geometry)"); var obj = new HazGeo
{
Id = ,
Geo = DbGeography.LineFromText("LINESTRING(-122.360 47.656, -122.343 47.656 )", ),
Geometry = DbGeometry.LineFromText("LINESTRING (100 100, 20 180, 180 180)", )
};
connection.Execute("insert #Geo(id, geo, geometry) values (@Id, @Geo, @Geometry)", obj);
var row = connection.Query<HazGeo>("select * from #Geo where id=1").SingleOrDefault();
row.IsNotNull();
row.Id.IsEqualTo();
row.Geo.IsNotNull();
row.Geometry.IsNotNull();
} public void SqlGeography_SO25538154()
{
Dapper.SqlMapper.ResetTypeHandlers();
connection.Execute("create table #SqlGeo (id int, geo geography, geometry geometry)"); var obj = new HazSqlGeo
{
Id = ,
Geo = SqlGeography.STLineFromText(new SqlChars(new SqlString("LINESTRING(-122.360 47.656, -122.343 47.656 )")), ),
Geometry = SqlGeometry.STLineFromText(new SqlChars(new SqlString("LINESTRING (100 100, 20 180, 180 180)")), )
};
connection.Execute("insert #SqlGeo(id, geo, geometry) values (@Id, @Geo, @Geometry)", obj);
var row = connection.Query<HazSqlGeo>("select * from #SqlGeo where id=1").SingleOrDefault();
row.IsNotNull();
row.Id.IsEqualTo();
row.Geo.IsNotNull();
row.Geometry.IsNotNull();
} public void SqlHierarchyId_SO18888911()
{
Dapper.SqlMapper.ResetTypeHandlers();
var row = connection.Query<HazSqlHierarchy>("select 3 as [Id], hierarchyid::Parse('/1/2/3/') as [Path]").Single();
row.Id.Equals();
row.Path.IsNotNull(); var val = connection.Query<SqlHierarchyId>("select @Path", row).Single();
val.IsNotNull();
} public class HazSqlHierarchy
{
public int Id { get; set; }
public SqlHierarchyId Path { get; set; }
}
#endif
public void TypeBasedViaDynamic()
{
Type type = GetSomeType(); dynamic template = Activator.CreateInstance(type);
dynamic actual = CheetViaDynamic(template, "select @A as [A], @B as [B]", new { A = , B = "abc" });
((object)actual).GetType().IsEqualTo(type);
int a = actual.A;
string b = actual.B;
a.IsEqualTo();
b.IsEqualTo("abc");
}
public void TypeBasedViaType()
{
Type type = GetSomeType(); dynamic actual = connection.Query(type, "select @A as [A], @B as [B]", new { A = , B = "abc" }).FirstOrDefault();
((object)actual).GetType().IsEqualTo(type);
int a = actual.A;
string b = actual.B;
a.IsEqualTo();
b.IsEqualTo("abc");
}
public void TypeBasedViaTypeMulti()
{
Type type = GetSomeType(); dynamic first, second;
using (var multi = connection.QueryMultiple("select @A as [A], @B as [B]; select @C as [A], @D as [B]",
new { A = , B = "abc", C = , D = "def" }))
{
first = multi.Read(type).Single();
second = multi.Read(type).Single();
}
((object)first).GetType().IsEqualTo(type);
int a = first.A;
string b = first.B;
a.IsEqualTo();
b.IsEqualTo("abc"); ((object)second).GetType().IsEqualTo(type);
a = second.A;
b = second.B;
a.IsEqualTo();
b.IsEqualTo("def");
}
T CheetViaDynamic<T>(T template, string query, object args)
{
return connection.Query<T>(query, args).SingleOrDefault();
}
static Type GetSomeType()
{
return typeof(SomeType);
}
public class SomeType
{
public int A { get; set; }
public string B { get; set; }
}
#if !DNXCORE50
class WithInit : ISupportInitialize
{
public string Value { get; set; }
public int Flags { get; set; } void ISupportInitialize.BeginInit()
{
Flags += ;
} void ISupportInitialize.EndInit()
{
Flags += ;
}
}
#endif
public void SO24607639_NullableBools()
{
var obj = connection.Query<HazBools>(
@"declare @vals table (A bit null, B bit null, C bit null);
insert @vals (A,B,C) values (1,0,null);
select * from @vals").Single();
obj.IsNotNull();
obj.A.Value.IsEqualTo(true);
obj.B.Value.IsEqualTo(false);
obj.C.IsNull();
}
class HazBools
{
public bool? A { get; set; }
public bool? B { get; set; }
public bool? C { get; set; }
} public void SO24605346_ProcsAndStrings()
{
connection.Execute(@"create proc #GetPracticeRebateOrderByInvoiceNumber @TaxInvoiceNumber nvarchar(20) as
select @TaxInvoiceNumber as [fTaxInvoiceNumber]");
string InvoiceNumber = "INV0000000028PPN";
var result = connection.Query<PracticeRebateOrders>("#GetPracticeRebateOrderByInvoiceNumber", new
{
TaxInvoiceNumber = InvoiceNumber
}, commandType: CommandType.StoredProcedure).FirstOrDefault(); result.TaxInvoiceNumber.IsEqualTo("INV0000000028PPN");
}
class PracticeRebateOrders
{
public string fTaxInvoiceNumber;
#if EXTERNALS
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
#endif
public string TaxInvoiceNumber { get { return fTaxInvoiceNumber; } set { fTaxInvoiceNumber = value; } }
} public class RatingValueHandler : Dapper.SqlMapper.TypeHandler<RatingValue>
{
private RatingValueHandler() { }
public static readonly RatingValueHandler Default = new RatingValueHandler();
public override RatingValue Parse(object value)
{
if (value is Int32)
return new RatingValue() { Value = (Int32)value }; throw new FormatException("Invalid conversion to RatingValue");
} public override void SetValue(IDbDataParameter parameter, RatingValue value)
{
// ... null, range checks etc ...
parameter.DbType = System.Data.DbType.Int32;
parameter.Value = value.Value;
}
}
public class RatingValue
{
public Int32 Value { get; set; }
// ... some other properties etc ...
} public class MyResult
{
public String CategoryName { get; set; }
public RatingValue CategoryRating { get; set; }
} public void SO24740733_TestCustomValueHandler()
{
Dapper.SqlMapper.AddTypeHandler(RatingValueHandler.Default);
var foo = connection.Query<MyResult>("SELECT 'Foo' AS CategoryName, 200 AS CategoryRating").Single(); foo.CategoryName.IsEqualTo("Foo");
foo.CategoryRating.Value.IsEqualTo();
} enum SO27024806Enum { Foo, Bar } private class SO27024806Class
{
public SO27024806Class(SO27024806Enum myField)
{
this.MyField = myField;
} public SO27024806Enum MyField { get; set; }
} public void SO27024806_TestVarcharEnumMemberWithExplicitConstructor()
{
var foo = connection.Query<SO27024806Class>("SELECT 'Foo' AS myField").Single();
foo.MyField.IsEqualTo(SO27024806Enum.Foo);
} public void SO24740733_TestCustomValueSingleColumn()
{
Dapper.SqlMapper.AddTypeHandler(RatingValueHandler.Default);
var foo = connection.Query<RatingValue>("SELECT 200 AS CategoryRating").Single(); foo.Value.IsEqualTo();
} public void Issue130_IConvertible()
{
dynamic row = connection.Query("select 1 as [a], '2' as [b]").Single();
int a = row.a;
string b = row.b;
a.IsEqualTo();
b.IsEqualTo(""); row = connection.Query<dynamic>("select 3 as [a], '4' as [b]").Single();
a = row.a;
b = row.b;
a.IsEqualTo();
b.IsEqualTo("");
} public void Issue22_ExecuteScalar()
{
int i = connection.ExecuteScalar<int>("select 123");
i.IsEqualTo(); i = connection.ExecuteScalar<int>("select cast(123 as bigint)");
i.IsEqualTo(); long j = connection.ExecuteScalar<long>("select 123");
j.IsEqualTo(123L); j = connection.ExecuteScalar<long>("select cast(123 as bigint)");
j.IsEqualTo(123L); int? k = connection.ExecuteScalar<int?>("select @i", new { i = default(int?) });
k.IsNull(); #if EXTERNALS
Dapper.EntityFramework.Handlers.Register();
var geo = DbGeography.LineFromText("LINESTRING(-122.360 47.656, -122.343 47.656 )", );
var geo2 = connection.ExecuteScalar<DbGeography>("select @geo", new { geo });
geo2.IsNotNull();
#endif
} public void Issue142_FailsNamedStatus()
{
var row1 = connection.Query<Issue142_Status>("select @Status as [Status]", new { Status = StatusType.Started }).Single();
row1.Status.IsEqualTo(StatusType.Started); var row2 = connection.Query<Issue142_StatusType>("select @Status as [Status]", new { Status = Status.Started }).Single();
row2.Status.IsEqualTo(Status.Started);
} public class Issue142_Status
{
public StatusType Status { get; set; }
}
public class Issue142_StatusType
{
public Status Status { get; set; }
} public enum StatusType : byte
{
NotStarted = , Started = , Finished =
}
public enum Status : byte
{
NotStarted = , Started = , Finished =
} public void Issue136_ValueTypeHandlers()
{
Dapper.SqlMapper.ResetTypeHandlers();
Dapper.SqlMapper.AddTypeHandler(typeof(LocalDate), LocalDateHandler.Default);
var param = new LocalDateResult
{
NotNullable = new LocalDate { Year = , Month = , Day = },
NullableNotNull = new LocalDate { Year = , Month = , Day = },
NullableIsNull = null,
}; var result = connection.Query<LocalDateResult>("SELECT @NotNullable AS NotNullable, @NullableNotNull AS NullableNotNull, @NullableIsNull AS NullableIsNull", param).Single(); Dapper.SqlMapper.ResetTypeHandlers();
Dapper.SqlMapper.AddTypeHandler(typeof(LocalDate?), LocalDateHandler.Default);
result = connection.Query<LocalDateResult>("SELECT @NotNullable AS NotNullable, @NullableNotNull AS NullableNotNull, @NullableIsNull AS NullableIsNull", param).Single();
}
public class LocalDateHandler : Dapper.SqlMapper.TypeHandler<LocalDate>
{
private LocalDateHandler() { } // Make the field type ITypeHandler to ensure it cannot be used with SqlMapper.AddTypeHandler<T>(TypeHandler<T>)
// by mistake.
public static readonly Dapper.SqlMapper.ITypeHandler Default = new LocalDateHandler(); public override LocalDate Parse(object value)
{
var date = (DateTime)value;
return new LocalDate { Year = date.Year, Month = date.Month, Day = date.Day };
} public override void SetValue(IDbDataParameter parameter, LocalDate value)
{
parameter.DbType = DbType.DateTime;
parameter.Value = new DateTime(value.Year, value.Month, value.Day);
}
} public struct LocalDate
{
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
} public class LocalDateResult
{
public LocalDate NotNullable { get; set; }
public LocalDate? NullableNotNull { get; set; }
public LocalDate? NullableIsNull { get; set; }
} public class LotsOfNumerics
{
public enum E_Byte : byte { A = , B = }
public enum E_SByte : sbyte { A = , B = }
public enum E_Short : short { A = , B = }
public enum E_UShort : ushort { A = , B = }
public enum E_Int : int { A = , B = }
public enum E_UInt : uint { A = , B = }
public enum E_Long : long { A = , B = }
public enum E_ULong : ulong { A = , B = } public E_Byte P_Byte { get; set; }
public E_SByte P_SByte { get; set; }
public E_Short P_Short { get; set; }
public E_UShort P_UShort { get; set; }
public E_Int P_Int { get; set; }
public E_UInt P_UInt { get; set; }
public E_Long P_Long { get; set; }
public E_ULong P_ULong { get; set; } public bool N_Bool { get; set; }
public byte N_Byte { get; set; }
public sbyte N_SByte { get; set; }
public short N_Short { get; set; }
public ushort N_UShort { get; set; }
public int N_Int { get; set; }
public uint N_UInt { get; set; }
public long N_Long { get; set; }
public ulong N_ULong { get; set; } public float N_Float { get; set; }
public double N_Double { get; set; }
public decimal N_Decimal { get; set; } public E_Byte? N_P_Byte { get; set; }
public E_SByte? N_P_SByte { get; set; }
public E_Short? N_P_Short { get; set; }
public E_UShort? N_P_UShort { get; set; }
public E_Int? N_P_Int { get; set; }
public E_UInt? N_P_UInt { get; set; }
public E_Long? N_P_Long { get; set; }
public E_ULong? N_P_ULong { get; set; } public bool? N_N_Bool { get; set; }
public byte? N_N_Byte { get; set; }
public sbyte? N_N_SByte { get; set; }
public short? N_N_Short { get; set; }
public ushort? N_N_UShort { get; set; }
public int? N_N_Int { get; set; }
public uint? N_N_UInt { get; set; }
public long? N_N_Long { get; set; }
public ulong? N_N_ULong { get; set; } public float? N_N_Float { get; set; }
public double? N_N_Double { get; set; }
public decimal? N_N_Decimal { get; set; }
} public void TestBigIntForEverythingWorks_SqlLite()
{
TestBigIntForEverythingWorks_SqlLite_ByDataType<long>("bigint");
TestBigIntForEverythingWorks_SqlLite_ByDataType<int>("int");
TestBigIntForEverythingWorks_SqlLite_ByDataType<byte>("tinyint");
TestBigIntForEverythingWorks_SqlLite_ByDataType<short>("smallint");
TestBigIntForEverythingWorks_SqlLite_ByDataType<bool>("bit");
TestBigIntForEverythingWorks_SqlLite_ByDataType<float>("float(24)");
TestBigIntForEverythingWorks_SqlLite_ByDataType<double>("float(53)");
}
private void TestBigIntForEverythingWorks_SqlLite_ByDataType<T>(string dbType)
{
using (var reader = connection.ExecuteReader("select cast(1 as " + dbType + ")"))
{
reader.Read().IsTrue();
reader.GetFieldType().Equals(typeof(T));
reader.Read().IsFalse();
reader.NextResult().IsFalse();
} string sql = "select " + string.Join(",", typeof(LotsOfNumerics).GetProperties().Select(
x => "cast (1 as " + dbType + ") as [" + x.Name + "]"));
var row = connection.Query<LotsOfNumerics>(sql).Single(); row.N_Bool.IsTrue();
row.N_SByte.IsEqualTo((sbyte));
row.N_Byte.IsEqualTo((byte));
row.N_Int.IsEqualTo((int));
row.N_UInt.IsEqualTo((uint));
row.N_Short.IsEqualTo((short));
row.N_UShort.IsEqualTo((ushort));
row.N_Long.IsEqualTo((long));
row.N_ULong.IsEqualTo((ulong));
row.N_Float.IsEqualTo((float));
row.N_Double.IsEqualTo((double));
row.N_Decimal.IsEqualTo((decimal)); row.P_Byte.IsEqualTo(LotsOfNumerics.E_Byte.B);
row.P_SByte.IsEqualTo(LotsOfNumerics.E_SByte.B);
row.P_Short.IsEqualTo(LotsOfNumerics.E_Short.B);
row.P_UShort.IsEqualTo(LotsOfNumerics.E_UShort.B);
row.P_Int.IsEqualTo(LotsOfNumerics.E_Int.B);
row.P_UInt.IsEqualTo(LotsOfNumerics.E_UInt.B);
row.P_Long.IsEqualTo(LotsOfNumerics.E_Long.B);
row.P_ULong.IsEqualTo(LotsOfNumerics.E_ULong.B); row.N_N_Bool.Value.IsTrue();
row.N_N_SByte.Value.IsEqualTo((sbyte));
row.N_N_Byte.Value.IsEqualTo((byte));
row.N_N_Int.Value.IsEqualTo((int));
row.N_N_UInt.Value.IsEqualTo((uint));
row.N_N_Short.Value.IsEqualTo((short));
row.N_N_UShort.Value.IsEqualTo((ushort));
row.N_N_Long.Value.IsEqualTo((long));
row.N_N_ULong.Value.IsEqualTo((ulong));
row.N_N_Float.Value.IsEqualTo((float));
row.N_N_Double.Value.IsEqualTo((double));
row.N_N_Decimal.IsEqualTo((decimal)); row.N_P_Byte.Value.IsEqualTo(LotsOfNumerics.E_Byte.B);
row.N_P_SByte.Value.IsEqualTo(LotsOfNumerics.E_SByte.B);
row.N_P_Short.Value.IsEqualTo(LotsOfNumerics.E_Short.B);
row.N_P_UShort.Value.IsEqualTo(LotsOfNumerics.E_UShort.B);
row.N_P_Int.Value.IsEqualTo(LotsOfNumerics.E_Int.B);
row.N_P_UInt.Value.IsEqualTo(LotsOfNumerics.E_UInt.B);
row.N_P_Long.Value.IsEqualTo(LotsOfNumerics.E_Long.B);
row.N_P_ULong.Value.IsEqualTo(LotsOfNumerics.E_ULong.B); TestBigIntForEverythingWorks<bool>(true, dbType);
TestBigIntForEverythingWorks<sbyte>((sbyte), dbType);
TestBigIntForEverythingWorks<byte>((byte), dbType);
TestBigIntForEverythingWorks<int>((int), dbType);
TestBigIntForEverythingWorks<uint>((uint), dbType);
TestBigIntForEverythingWorks<short>((short), dbType);
TestBigIntForEverythingWorks<ushort>((ushort), dbType);
TestBigIntForEverythingWorks<long>((long), dbType);
TestBigIntForEverythingWorks<ulong>((ulong), dbType);
TestBigIntForEverythingWorks<float>((float), dbType);
TestBigIntForEverythingWorks<double>((double), dbType);
TestBigIntForEverythingWorks<decimal>((decimal), dbType); TestBigIntForEverythingWorks(LotsOfNumerics.E_Byte.B, dbType);
TestBigIntForEverythingWorks(LotsOfNumerics.E_SByte.B, dbType);
TestBigIntForEverythingWorks(LotsOfNumerics.E_Int.B, dbType);
TestBigIntForEverythingWorks(LotsOfNumerics.E_UInt.B, dbType);
TestBigIntForEverythingWorks(LotsOfNumerics.E_Short.B, dbType);
TestBigIntForEverythingWorks(LotsOfNumerics.E_UShort.B, dbType);
TestBigIntForEverythingWorks(LotsOfNumerics.E_Long.B, dbType);
TestBigIntForEverythingWorks(LotsOfNumerics.E_ULong.B, dbType); TestBigIntForEverythingWorks<bool?>(true, dbType);
TestBigIntForEverythingWorks<sbyte?>((sbyte), dbType);
TestBigIntForEverythingWorks<byte?>((byte), dbType);
TestBigIntForEverythingWorks<int?>((int), dbType);
TestBigIntForEverythingWorks<uint?>((uint), dbType);
TestBigIntForEverythingWorks<short?>((short), dbType);
TestBigIntForEverythingWorks<ushort?>((ushort), dbType);
TestBigIntForEverythingWorks<long?>((long), dbType);
TestBigIntForEverythingWorks<ulong?>((ulong), dbType);
TestBigIntForEverythingWorks<float?>((float), dbType);
TestBigIntForEverythingWorks<double?>((double), dbType);
TestBigIntForEverythingWorks<decimal?>((decimal), dbType); TestBigIntForEverythingWorks<LotsOfNumerics.E_Byte?>(LotsOfNumerics.E_Byte.B, dbType);
TestBigIntForEverythingWorks<LotsOfNumerics.E_SByte?>(LotsOfNumerics.E_SByte.B, dbType);
TestBigIntForEverythingWorks<LotsOfNumerics.E_Int?>(LotsOfNumerics.E_Int.B, dbType);
TestBigIntForEverythingWorks<LotsOfNumerics.E_UInt?>(LotsOfNumerics.E_UInt.B, dbType);
TestBigIntForEverythingWorks<LotsOfNumerics.E_Short?>(LotsOfNumerics.E_Short.B, dbType);
TestBigIntForEverythingWorks<LotsOfNumerics.E_UShort?>(LotsOfNumerics.E_UShort.B, dbType);
TestBigIntForEverythingWorks<LotsOfNumerics.E_Long?>(LotsOfNumerics.E_Long.B, dbType);
TestBigIntForEverythingWorks<LotsOfNumerics.E_ULong?>(LotsOfNumerics.E_ULong.B, dbType);
} private void TestBigIntForEverythingWorks<T>(T expected, string dbType)
{
var query = connection.Query<T>("select cast(1 as " + dbType + ")").Single();
query.IsEqualTo(expected); var scalar = connection.ExecuteScalar<T>("select cast(1 as " + dbType + ")");
scalar.IsEqualTo(expected);
} public void TestSubsequentQueriesSuccess()
{
var data0 = connection.Query<Fooz0>("select 1 as [Id] where 1 = 0").ToList();
data0.Count().IsEqualTo(); var data1 = connection.Query<Fooz1>(new CommandDefinition("select 1 as [Id] where 1 = 0", flags: CommandFlags.Buffered)).ToList();
data1.Count().IsEqualTo(); var data2 = connection.Query<Fooz2>(new CommandDefinition("select 1 as [Id] where 1 = 0", flags: CommandFlags.None)).ToList();
data2.Count().IsEqualTo(); data0 = connection.Query<Fooz0>("select 1 as [Id] where 1 = 0").ToList();
data0.Count().IsEqualTo(); data1 = connection.Query<Fooz1>(new CommandDefinition("select 1 as [Id] where 1 = 0", flags: CommandFlags.Buffered)).ToList();
data1.Count().IsEqualTo(); data2 = connection.Query<Fooz2>(new CommandDefinition("select 1 as [Id] where 1 = 0", flags: CommandFlags.None)).ToList();
data2.Count().IsEqualTo();
}
class Fooz0 { public int Id { get; set; } }
class Fooz1 { public int Id { get; set; } }
class Fooz2 { public int Id { get; set; } } public void SO25069578_DynamicParams_Procs()
{
var parameters = new DynamicParameters();
parameters.Add("foo", "bar");
// parameters = new DynamicParameters(parameters);
try { connection.Execute("drop proc SO25069578"); }
catch { }
connection.Execute("create proc SO25069578 @foo nvarchar(max) as select @foo as [X]");
var tran = connection.BeginTransaction(); // gist used transaction; behaves the same either way, though
var row = connection.Query<HazX>("SO25069578", parameters,
commandType: CommandType.StoredProcedure, transaction: tran).Single();
tran.Rollback();
row.X.IsEqualTo("bar");
} public void Issue149_TypeMismatch_SequentialAccess()
{
string error;
Guid guid = Guid.Parse("cf0ef7ac-b6fe-4e24-aeda-a2b45bb5654e");
try
{
var result = connection.Query<Issue149_Person>(@"select @guid as Id", new { guid }).First();
error = null;
}
catch (Exception ex)
{
error = ex.Message;
}
error.IsEqualTo("Error parsing column 0 (Id=cf0ef7ac-b6fe-4e24-aeda-a2b45bb5654e - Object)");
}
public class Issue149_Person { public string Id { get; set; } } public class HazX
{
public string X { get; set; }
} public void SO25297173_DynamicIn()
{
var query = @"
declare @table table(value int not null);
insert @table values(1);
insert @table values(2);
insert @table values(3);
insert @table values(4);
insert @table values(5);
insert @table values(6);
insert @table values(7);
SELECT value FROM @table WHERE value IN @myIds";
var queryParams = new Dictionary<string, object> {
{ "myIds", new [] { , } }
}; var dynamicParams = new DynamicParameters(queryParams);
List<int> result = connection.Query<int>(query, dynamicParams).ToList();
result.Count.IsEqualTo();
result.Contains().IsTrue();
result.Contains().IsTrue();
} public void AllowIDictionaryParameters()
{
var parameters = new Dictionary<string, object>
{
{ "param1", }
}; connection.Query("SELECT @param1", parameters);
} public void Issue178_SqlServer()
{
const string sql = @"select count(*) from Issue178";
try { connection.Execute("drop table Issue178"); }
catch { }
try { connection.Execute("create table Issue178(id int not null)"); }
catch { }
// raw ADO.net
var sqlCmd = new SqlCommand(sql, connection);
using (IDataReader reader1 = sqlCmd.ExecuteReader())
{
Assert.IsTrue(reader1.Read());
reader1.GetInt32().IsEqualTo();
Assert.IsFalse(reader1.Read());
Assert.IsFalse(reader1.NextResult());
} // dapper
using (var reader2 = connection.ExecuteReader(sql))
{
Assert.IsTrue(reader2.Read());
reader2.GetInt32().IsEqualTo();
Assert.IsFalse(reader2.Read());
Assert.IsFalse(reader2.NextResult());
}
}
#if EXTERNALS
public void Issue178_Firebird() // we expect this to fail due to a bug in Firebird; a PR to fix it has been submitted
{
var cs = @"initial catalog=localhost:database;user id=SYSDBA;password=masterkey"; using (var connection = new FbConnection(cs))
{
connection.Open();
const string sql = @"select count(*) from Issue178";
try { connection.Execute("drop table Issue178"); }
catch { }
connection.Execute("create table Issue178(id int not null)");
connection.Execute("insert into Issue178(id) values(42)");
// raw ADO.net
using (var sqlCmd = new FbCommand(sql, connection))
using (IDataReader reader1 = sqlCmd.ExecuteReader())
{
Assert.IsTrue(reader1.Read());
reader1.GetInt32().IsEqualTo();
Assert.IsFalse(reader1.Read());
Assert.IsFalse(reader1.NextResult());
} // dapper
using (var reader2 = connection.ExecuteReader(sql))
{
Assert.IsTrue(reader2.Read());
reader2.GetInt32().IsEqualTo();
Assert.IsFalse(reader2.Read());
Assert.IsFalse(reader2.NextResult());
} var count = connection.Query<int>(sql).Single();
count.IsEqualTo();
}
} public void PseudoPositionalParameters_Simple()
{
using (var connection = ConnectViaOledb())
{
int value = connection.Query<int>("select ?x? + ?y_2? + ?z?", new { x = , y_2 = , z = , z2 = }).Single();
value.IsEqualTo();
}
} public void PseudoPositionalParameters_Dynamic()
{
using (var connection = ConnectViaOledb())
{
var args = new DynamicParameters();
args.Add("x", );
args.Add("y_2", );
args.Add("z", );
args.Add("z2", );
int value = connection.Query<int>("select ?x? + ?y_2? + ?z?", args).Single();
value.IsEqualTo();
}
} public void PseudoPositionalParameters_ReusedParameter()
{
using (var connection = ConnectViaOledb())
{
try
{
int value = connection.Query<int>("select ?x? + ?y_2? + ?x?", new { x = , y_2 = }).Single();
Assert.Fail();
}
catch (InvalidOperationException ex)
{
ex.Message.IsEqualTo("When passing parameters by position, each parameter can only be referenced once");
}
}
} public void PseudoPositionalParameters_ExecSingle()
{
using (var connection = ConnectViaOledb())
{
var data = new { x = };
connection.Execute("create table #named_single(val int not null)");
int count = connection.Execute("insert #named_single (val) values (?x?)", data);
int sum = (int)connection.ExecuteScalar("select sum(val) from #named_single");
count.IsEqualTo();
sum.IsEqualTo();
}
}
public void PseudoPositionalParameters_ExecMulti()
{
using (var connection = ConnectViaOledb())
{
var data = new[]
{
new { x = , y = },
new { x = , y = },
new { x = , y = },
};
connection.Execute("create table #named_multi(val int not null)");
int count = connection.Execute("insert #named_multi (val) values (?x?)", data);
int sum = (int)connection.ExecuteScalar("select sum(val) from #named_multi");
count.IsEqualTo();
sum.IsEqualTo();
}
}
#endif
public void QueryBasicWithoutQuery()
{
int? i = connection.Query<int?>("print 'not a query'").FirstOrDefault();
i.IsNull();
} public void QueryComplexWithoutQuery()
{
var obj = connection.Query<Foo1>("print 'not a query'").FirstOrDefault();
obj.IsNull();
} public void Issue182_BindDynamicObjectParametersAndColumns()
{
connection.Execute("create table #Dyno ([Id] uniqueidentifier primary key, [Name] nvarchar(50) not null, [Foo] bigint not null);"); var guid = Guid.NewGuid();
var orig = new Dyno { Name = "T Rex", Id = guid, Foo = 123L };
var result = connection.Execute("insert into #Dyno ([Id], [Name], [Foo]) values (@Id, @Name, @Foo);", orig); var fromDb = connection.Query<Dyno>("select * from #Dyno where Id=@Id", orig).Single();
((Guid)fromDb.Id).IsEqualTo(guid);
fromDb.Name.IsEqualTo("T Rex");
((long)fromDb.Foo).IsEqualTo(123L);
}
public class Dyno
{
public dynamic Id { get; set; }
public string Name { get; set; } public object Foo { get; set; }
} public void Issue151_ExpandoObjectArgsQuery()
{
dynamic args = new ExpandoObject();
args.Id = ;
args.Name = "abc"; var row = connection.Query("select @Id as [Id], @Name as [Name]", (object)args).Single();
((int)row.Id).Equals();
((string)row.Name).Equals("abc");
} public void Issue151_ExpandoObjectArgsExec()
{
dynamic args = new ExpandoObject();
args.Id = ;
args.Name = "abc";
connection.Execute("create table #issue151 (Id int not null, Name nvarchar(20) not null)");
connection.Execute("insert #issue151 values(@Id, @Name)", (object)args).IsEqualTo();
var row = connection.Query("select Id, Name from #issue151").Single();
((int)row.Id).Equals();
((string)row.Name).Equals("abc");
} public void Issue192_InParameterWorksWithSimilarNames()
{
var rows = connection.Query(@"
declare @Issue192 table (
Field INT NOT NULL PRIMARY KEY IDENTITY(1,1),
Field_1 INT NOT NULL);
insert @Issue192(Field_1) values (1), (2), (3);
SELECT * FROM @Issue192 WHERE Field IN @Field AND Field_1 IN @Field_1",
new { Field = new[] { , }, Field_1 = new[] { , } }).Single();
((int)rows.Field).IsEqualTo();
((int)rows.Field_1).IsEqualTo();
} public void Issue192_InParameterWorksWithSimilarNamesWithUnicode()
{
var rows = connection.Query(@"
declare @Issue192 table (
Field INT NOT NULL PRIMARY KEY IDENTITY(1,1),
Field_1 INT NOT NULL);
insert @Issue192(Field_1) values (1), (2), (3);
SELECT * FROM @Issue192 WHERE Field IN @µ AND Field_1 IN @µµ",
new { µ = new[] { , }, µµ = new[] { , } }).Single();
((int)rows.Field).IsEqualTo();
((int)rows.Field_1).IsEqualTo();
} class _ExplicitConstructors
{
public int Field { get; set; }
public int Field_1 { get; set; } private bool WentThroughProperConstructor; public _ExplicitConstructors() { } [ExplicitConstructor]
public _ExplicitConstructors(string foo, int bar)
{
WentThroughProperConstructor = true;
} public bool GetWentThroughProperConstructor()
{
return WentThroughProperConstructor;
}
} public void ExplicitConstructors()
{
var rows = connection.Query<_ExplicitConstructors>(@"
declare @ExplicitConstructors table (
Field INT NOT NULL PRIMARY KEY IDENTITY(1,1),
Field_1 INT NOT NULL);
insert @ExplicitConstructors(Field_1) values (1);
SELECT * FROM @ExplicitConstructors"
).ToList(); rows.Count.IsEqualTo();
rows[].Field.IsEqualTo();
rows[].Field_1.IsEqualTo();
rows[].GetWentThroughProperConstructor().IsTrue();
} public void Issue220_InParameterCanBeSpecifiedInAnyCase()
{
// note this might fail if your database server is case-sensitive
connection.Query<int>("select * from (select 1 as Id) as X where Id in @ids", new { Ids = new[] { } })
.IsSequenceEqualTo(new[] { });
} public void SO29343103_UtcDates()
{
const string sql = "select @date";
var date = DateTime.UtcNow;
var returned = connection.Query<DateTime>(sql, new { date }).Single();
var delta = returned - date;
Assert.IsTrue(delta.TotalMilliseconds >= - && delta.TotalMilliseconds <= );
}
#if DNXCORE50
[FrameworkFail("https://github.com/dotnet/corefx/issues/1612")]
#endif
public void Issue261_Decimals()
{
var parameters = new DynamicParameters();
parameters.Add("c", dbType: DbType.Decimal, direction: ParameterDirection.Output, precision: , scale: );
connection.Execute("create proc #Issue261 @c decimal(10,5) OUTPUT as begin set @c=11.884 end");
connection.Execute("#Issue261", parameters, commandType: CommandType.StoredProcedure);
var c = parameters.Get<Decimal>("c");
c.IsEqualTo(11.884M);
}
#if DNXCORE50
[FrameworkFail("https://github.com/dotnet/corefx/issues/1612")]
#endif
public void Issue261_Decimals_ADONET_SetViaBaseClass()
{
Issue261_Decimals_ADONET(true);
} public void Issue261_Decimals_ADONET_SetViaConcreteClass()
{
Issue261_Decimals_ADONET(false);
}
private void Issue261_Decimals_ADONET(bool setPrecisionScaleViaAbstractApi)
{
try
{
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = "create proc #Issue261Direct @c decimal(10,5) OUTPUT as begin set @c=11.884 end";
cmd.ExecuteNonQuery();
}
}
catch { /* we don't care that it already exists */ } using (var cmd = connection.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "#Issue261Direct";
var c = cmd.CreateParameter();
c.ParameterName = "c";
c.Direction = ParameterDirection.Output;
c.Value = DBNull.Value;
c.DbType = DbType.Decimal; if (setPrecisionScaleViaAbstractApi)
{
#if DNXCORE50
DbParameter baseParam = c;
#else
IDbDataParameter baseParam = c;
#endif
baseParam.Precision = ;
baseParam.Scale = ;
}
else
{
c.Precision = ;
c.Scale = ;
} cmd.Parameters.Add(c);
cmd.ExecuteNonQuery();
decimal value = (decimal)c.Value;
value.IsEqualTo(11.884M);
}
} public void BasicDecimals()
{
var c = connection.Query<decimal>("select @c", new { c = 11.884M }).Single();
c.IsEqualTo(11.884M);
}
[SkipTest]
public void Issue263_Timeout()
{
var watch = Stopwatch.StartNew();
var i = connection.Query<int>("waitfor delay '00:01:00'; select 42;", commandTimeout: , buffered: false).Single();
watch.Stop();
i.IsEqualTo();
var minutes = watch.ElapsedMilliseconds / / ;
Assert.IsTrue(minutes >= 0.95 && minutes <= 1.05);
}
#if EXTERNALS
public void SO29596645_TvpProperty()
{
try { connection.Execute("CREATE TYPE SO29596645_ReminderRuleType AS TABLE (id int NOT NULL)"); }
catch { }
connection.Execute(@"create proc #SO29596645_Proc (@Id int, @Rules SO29596645_ReminderRuleType READONLY)
as begin select @Id + ISNULL((select sum(id) from @Rules), 0); end");
var obj = new SO29596645_OrganisationDTO();
int val = connection.Query<int>("#SO29596645_Proc", obj.Rules, commandType: CommandType.StoredProcedure).Single(); // 4 + 9 + 7 = 20
val.IsEqualTo(); }
#endif
public void Issue268_ReturnQueryMultiple()
{
connection.Execute(@"create proc #TestProc268 (@a int, @b int, @c int)as
begin
select @a;
select @b
return @c;
end"); var p = new DynamicParameters(new { a = , b = , c = });
p.Add("RetVal", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue); using (var reader = connection.QueryMultiple("#TestProc268", p, commandType: CommandType.StoredProcedure))
{
reader.Read();
}
var retVal = p.Get<int>("RetVal");
retVal.IsEqualTo();
}
#if EXTERNALS
class SO29596645_RuleTableValuedParameters : Dapper.SqlMapper.IDynamicParameters {
private string parameterName; public SO29596645_RuleTableValuedParameters(string parameterName)
{
this.parameterName = parameterName;
} public void AddParameters(IDbCommand command, Dapper.SqlMapper.Identity identity)
{
Console.WriteLine("> AddParameters");
SqlCommand lazy = (SqlCommand)command;
lazy.Parameters.AddWithValue("Id", );
DataTable table = new DataTable {
Columns = {{"Id", typeof(int)}},
Rows = {{}, {}}
};
lazy.Parameters.AddWithValue("Rules", table);
Console.WriteLine("< AddParameters");
}
}
class SO29596645_OrganisationDTO
{
public SO29596645_RuleTableValuedParameters Rules { get; private set; } public SO29596645_OrganisationDTO()
{
Rules = new SO29596645_RuleTableValuedParameters("@Rules");
}
}
#endif
#if POSTGRESQL class Cat
{
public int Id { get; set; }
public string Breed { get; set; }
public string Name { get; set; }
} Cat[] Cats = {
new Cat() { Breed = "Abyssinian", Name="KACTUS"},
new Cat() { Breed = "Aegean cat", Name="KADAFFI"},
new Cat() { Breed = "American Bobtail", Name="KANJI"},
new Cat() { Breed = "Balinese", Name="MACARONI"},
new Cat() { Breed = "Bombay", Name="MACAULAY"},
new Cat() { Breed = "Burmese", Name="MACBETH"},
new Cat() { Breed = "Chartreux", Name="MACGYVER"},
new Cat() { Breed = "German Rex", Name="MACKENZIE"},
new Cat() { Breed = "Javanese", Name="MADISON"},
new Cat() { Breed = "Persian", Name="MAGNA"}
}; public void TestPostresqlArrayParameters()
{
using (var conn = new NpgsqlConnection("Server=localhost;Port=5432;User Id=dappertest;Password=dapperpass;Database=dappertest;Encoding=UNICODE"))
{
conn.Open();
IDbTransaction transaction = conn.BeginTransaction();
conn.Execute("create table tcat ( id serial not null, breed character varying(20) not null, name character varying (20) not null);");
conn.Execute("insert into tcat(breed, name) values(:breed, :name) ", Cats); var r = conn.Query<Cat>("select * from tcat where id=any(:catids)", new { catids = new[] { , , } });
r.Count().IsEqualTo();
r.Count(c => c.Id == ).IsEqualTo();
r.Count(c => c.Id == ).IsEqualTo();
r.Count(c => c.Id == ).IsEqualTo();
transaction.Rollback();
}
}
#endif public void SO30156367_DynamicParamsWithoutExec()
{
var dbParams = new DynamicParameters();
dbParams.Add("Field1", );
var value = dbParams.Get<int>("Field1");
value.IsEqualTo();
} public void SO30435185_InvalidTypeOwner()
{
try {
string sql = @" INSERT INTO #XXX
(XXXId, AnotherId, ThirdId, Value, Comment)
VALUES
(@XXXId, @AnotherId, @ThirdId, @Value, @Comment); select @@rowcount as [Foo]"; var command = new
{
MyModels = new[]
{
new {XXXId = , AnotherId = , ThirdId = , Value = "abc", Comment = "def" }
}
};
var parameters = command
.MyModels
.Select(model => new
{
XXXId = model.XXXId,
AnotherId = model.AnotherId,
ThirdId = model.ThirdId,
Value = model.Value,
Comment = model.Comment
})
.ToArray(); var rowcount = (int)connection.Query(sql, parameters).Single().Foo;
rowcount.IsEqualTo(); Assert.Fail();
} catch(InvalidOperationException ex)
{
ex.Message.IsEqualTo("An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context");
}
}
}
}
Status API Training Shop Blog About
© GitHub, Inc. Terms Privacy Security Contact

最新文章

  1. Atitit 常用二维码对比(QR、PDF417、DM、汉信码 Aztec code maxicode
  2. win10调用局域网内xp系统上的打印机
  3. java的访问权限
  4. JQ引用
  5. mysql 错误代码汇总
  6. 百度地图API调用实例之地址标注与位置显示
  7. 解决struts2配置文件没有提示的问题
  8. C——货物管理系统
  9. Rancher安装使用
  10. uos事件控制块与任务同步
  11. Java数据结构整理(一)
  12. MarkDown 常用语法教程
  13. Java equals() 和hashCode()方法详解
  14. DDCTF 2018线上赛writeup
  15. struts2实现XML异步交互
  16. CreateThread和_beginthread区别及使用
  17. Windows 清理磁盘
  18. 通过Word 2016 发布的内容
  19. tomcat 、eclipse插件安装、一个机器安装多个tomcat、tomcat闪退的问题解决
  20. GridView分页的实现 ASP.NET c#(转)特好用

热门文章

  1. c语言指针难点
  2. DNA比对
  3. PHP读书笔记(6)- 数组
  4. Org-mode 任务添加提醒
  5. 【基本计数方法---加法原理和乘法原理】UVa 11538 - Chess Queen
  6. centos下安装usb摄像头驱动
  7. windows下编辑过的文件在Linux下用vi打开行尾会多出一个^M符号
  8. .NET学习笔记(1)— C#学习路线图
  9. CXF(2.7.10) - RESTful Services, JSON Support
  10. MyBatis(3.2.3) - One-to-many mapping