Commit 16325e85 authored by Johan Danforth's avatar Johan Danforth

Async methods now supports lists of entities

parent d6e068d3
...@@ -194,6 +194,9 @@ public static partial class SqlMapperExtensions ...@@ -194,6 +194,9 @@ public static partial class SqlMapperExtensions
var type = typeof(T); var type = typeof(T);
if (type.IsArray || type.IsGenericType)
type = type.GetGenericArguments()[0];
var keyProperties = KeyPropertiesCache(type); var keyProperties = KeyPropertiesCache(type);
if (!keyProperties.Any()) if (!keyProperties.Any())
throw new ArgumentException("Entity must have at least one [Key] property"); throw new ArgumentException("Entity must have at least one [Key] property");
...@@ -240,6 +243,9 @@ public static partial class SqlMapperExtensions ...@@ -240,6 +243,9 @@ public static partial class SqlMapperExtensions
var type = typeof(T); var type = typeof(T);
if (type.IsArray || type.IsGenericType)
type = type.GetGenericArguments()[0];
var keyProperties = KeyPropertiesCache(type); var keyProperties = KeyPropertiesCache(type);
if (!keyProperties.Any()) if (!keyProperties.Any())
throw new ArgumentException("Entity must have at least one [Key] property"); throw new ArgumentException("Entity must have at least one [Key] property");
......
using System.Data; using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlServerCe; using System.Data.SqlServerCe;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Dapper.Contrib.Extensions;
using System.Collections.Generic;
using System;
using Dapper;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapper.Contrib.Extensions;
namespace Dapper.Contrib.Tests namespace Dapper.Contrib.Tests
{ {
...@@ -28,13 +26,14 @@ public async Task TableNameAsync() ...@@ -28,13 +26,14 @@ public async Task TableNameAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>(); await connection.DeleteAllAsync<User>();
// tests against "Automobiles" table (Table attribute) // tests against "Automobiles" table (Table attribute)
await connection.InsertAsync(new Car { Name = "Volvo" }); await connection.InsertAsync(new Car { Name = "Volvo" });
(await connection.GetAsync<Car>(1)).Name.IsEqualTo("Volvo"); (await connection.GetAsync<Car>(1)).Name.IsEqualTo("Volvo");
(await connection.UpdateAsync(new Car() { Id = 1, Name = "Saab" })).IsEqualTo(true); (await connection.UpdateAsync(new Car { Id = 1, Name = "Saab" })).IsEqualTo(true);
(await connection.GetAsync<Car>(1)).Name.IsEqualTo("Saab"); (await connection.GetAsync<Car>(1)).Name.IsEqualTo("Saab");
(await connection.DeleteAsync(new Car() { Id = 1 })).IsEqualTo(true); (await connection.DeleteAsync(new Car { Id = 1 })).IsEqualTo(true);
(await connection.GetAsync<Car>(1)).IsNull(); (await connection.GetAsync<Car>(1)).IsNull();
} }
} }
...@@ -43,10 +42,11 @@ public async Task TestSimpleGetAsync() ...@@ -43,10 +42,11 @@ public async Task TestSimpleGetAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>(); await connection.DeleteAllAsync<User>();
var id = await connection.InsertAsync(new User { Name = "Adama", Age = 10 }); var id = await connection.InsertAsync(new User { Name = "Adama", Age = 10 });
var user = await connection.GetAsync<User>(id); var user = await connection.GetAsync<User>(id);
user.Id.IsEqualTo((int)id); user.Id.IsEqualTo(id);
user.Name.IsEqualTo("Adama"); user.Name.IsEqualTo("Adama");
await connection.DeleteAsync(user); await connection.DeleteAsync(user);
} }
...@@ -56,7 +56,8 @@ public async Task InsertGetUpdateAsync() ...@@ -56,7 +56,8 @@ public async Task InsertGetUpdateAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>(); await connection.DeleteAllAsync<User>();
(await connection.GetAsync<User>(3)).IsNull(); (await connection.GetAsync<User>(3)).IsNull();
var id = await connection.InsertAsync(new User { Name = "Adam", Age = 10 }); var id = await connection.InsertAsync(new User { Name = "Adam", Age = 10 });
...@@ -64,16 +65,17 @@ public async Task InsertGetUpdateAsync() ...@@ -64,16 +65,17 @@ public async Task InsertGetUpdateAsync()
//get a user with "isdirty" tracking //get a user with "isdirty" tracking
var user = await connection.GetAsync<IUser>(id); var user = await connection.GetAsync<IUser>(id);
user.Name.IsEqualTo("Adam"); user.Name.IsEqualTo("Adam");
(await connection.UpdateAsync(user)).IsEqualTo(false); //returns false if not updated, based on tracking (await connection.UpdateAsync(user)).IsEqualTo(false); //returns false if not updated, based on tracking
user.Name = "Bob"; user.Name = "Bob";
(await connection.UpdateAsync(user)).IsEqualTo(true); //returns true if updated, based on tracking (await connection.UpdateAsync(user)).IsEqualTo(true); //returns true if updated, based on tracking
user = await connection.GetAsync<IUser>(id); user = await connection.GetAsync<IUser>(id);
user.Name.IsEqualTo("Bob"); user.Name.IsEqualTo("Bob");
//get a user with no tracking //get a user with no tracking
var notrackedUser = await connection.GetAsync<User>(id); var notrackedUser = await connection.GetAsync<User>(id);
notrackedUser.Name.IsEqualTo("Bob"); notrackedUser.Name.IsEqualTo("Bob");
(await connection.UpdateAsync(notrackedUser)).IsEqualTo(true); //returns true, even though user was not changed (await connection.UpdateAsync(notrackedUser)).IsEqualTo(true);
//returns true, even though user was not changed
notrackedUser.Name = "Cecil"; notrackedUser.Name = "Cecil";
(await connection.UpdateAsync(notrackedUser)).IsEqualTo(true); (await connection.UpdateAsync(notrackedUser)).IsEqualTo(true);
(await connection.GetAsync<User>(id)).Name.IsEqualTo("Cecil"); (await connection.GetAsync<User>(id)).Name.IsEqualTo("Cecil");
...@@ -82,7 +84,7 @@ public async Task InsertGetUpdateAsync() ...@@ -82,7 +84,7 @@ public async Task InsertGetUpdateAsync()
(await connection.DeleteAsync(user)).IsEqualTo(true); (await connection.DeleteAsync(user)).IsEqualTo(true);
(await connection.QueryAsync<User>("select * from Users")).Count().IsEqualTo(0); (await connection.QueryAsync<User>("select * from Users")).Count().IsEqualTo(0);
(await connection.UpdateAsync(notrackedUser)).IsEqualTo(false); //returns false, user not found (await connection.UpdateAsync(notrackedUser)).IsEqualTo(false); //returns false, user not found
} }
} }
...@@ -90,10 +92,11 @@ public async Task InsertCheckKeyAsync() ...@@ -90,10 +92,11 @@ public async Task InsertCheckKeyAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>(); await connection.DeleteAllAsync<User>();
(await connection.GetAsync<IUser>(3)).IsNull(); (await connection.GetAsync<IUser>(3)).IsNull();
User user = new User { Name = "Adamb", Age = 10 }; var user = new User { Name = "Adamb", Age = 10 };
int id = (int)await connection.InsertAsync(user); var id = await connection.InsertAsync(user);
user.Id.IsEqualTo(id); user.Id.IsEqualTo(id);
} }
} }
...@@ -102,14 +105,15 @@ public async Task BuilderSelectClauseAsync() ...@@ -102,14 +105,15 @@ public async Task BuilderSelectClauseAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>(); await connection.DeleteAllAsync<User>();
var rand = new Random(8675309); var rand = new Random(8675309);
var data = new List<User>(); var data = new List<User>();
for (int i = 0; i < 100; i++) for (var i = 0; i < 100; i++)
{ {
var nU = new User { Age = rand.Next(70), Id = i, Name = Guid.NewGuid().ToString() }; var nU = new User { Age = rand.Next(70), Id = i, Name = Guid.NewGuid().ToString() };
data.Add(nU); data.Add(nU);
nU.Id = (int)await connection.InsertAsync<User>(nU); nU.Id = await connection.InsertAsync(nU);
} }
var builder = new SqlBuilder(); var builder = new SqlBuilder();
...@@ -124,7 +128,8 @@ public async Task BuilderSelectClauseAsync() ...@@ -124,7 +128,8 @@ public async Task BuilderSelectClauseAsync()
foreach (var u in data) foreach (var u in data)
{ {
if (!ids.Any(i => u.Id == i)) throw new Exception("Missing ids in select"); if (!ids.Any(i => u.Id == i)) throw new Exception("Missing ids in select");
if (!users.Any(a => a.Id == u.Id && a.Name == u.Name && a.Age == u.Age)) throw new Exception("Missing users in select"); if (!users.Any(a => a.Id == u.Id && a.Name == u.Name && a.Age == u.Age))
throw new Exception("Missing users in select");
} }
} }
} }
...@@ -139,7 +144,8 @@ public async Task BuilderTemplateWOCompositionAsync() ...@@ -139,7 +144,8 @@ public async Task BuilderTemplateWOCompositionAsync()
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>(); await connection.DeleteAllAsync<User>();
await connection.InsertAsync(new User { Age = 5, Name = "Testy McTestington" }); await connection.InsertAsync(new User { Age = 5, Name = "Testy McTestington" });
if ((await connection.QueryAsync<int>(template.RawSql, template.Parameters)).Single() != 1) if ((await connection.QueryAsync<int>(template.RawSql, template.Parameters)).Single() != 1)
...@@ -157,19 +163,70 @@ public async Task InsertListAsync() ...@@ -157,19 +163,70 @@ public async Task InsertListAsync()
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>(); await connection.DeleteAllAsync<User>();
var total = await connection.InsertAsync(users);
total.IsEqualTo(numberOfEntities);
users = connection.Query<User>("select * from users").ToList();
users.Count.IsEqualTo(numberOfEntities);
}
}
public async Task UpdateList()
{
const int numberOfEntities = 100;
var users = new List<User>();
for (var i = 0; i < numberOfEntities; i++)
users.Add(new User { Name = "User " + i, Age = i });
using (var connection = GetOpenConnection())
{
await connection.DeleteAllAsync<User>();
var total = await connection.InsertAsync(users); var total = await connection.InsertAsync(users);
total.IsEqualTo(numberOfEntities); total.IsEqualTo(numberOfEntities);
users = connection.Query<User>("select * from users").ToList(); users = connection.Query<User>("select * from users").ToList();
users.Count.IsEqualTo(numberOfEntities); users.Count.IsEqualTo(numberOfEntities);
foreach (var user in users)
{
user.Name = user.Name + " updated";
}
await connection.UpdateAsync(users);
var name = connection.Query<User>("select * from users").First().Name;
name.Contains("updated").IsTrue();
}
}
public async Task DeleteList()
{
const int numberOfEntities = 100;
var users = new List<User>();
for (var i = 0; i < numberOfEntities; i++)
users.Add(new User { Name = "User " + i, Age = i });
using (var connection = GetOpenConnection())
{
await connection.DeleteAllAsync<User>();
var total = await connection.InsertAsync(users);
total.IsEqualTo(numberOfEntities);
users = connection.Query<User>("select * from users").ToList();
users.Count.IsEqualTo(numberOfEntities);
var usersToDelete = users.Take(10).ToList();
await connection.DeleteAsync(usersToDelete);
users = connection.Query<User>("select * from users").ToList();
users.Count.IsEqualTo(numberOfEntities - 10);
} }
} }
public async Task GetAllAsync() public async Task GetAllAsync()
{ {
const int numberOfEntities = 10000; const int numberOfEntities = 1000;
var users = new List<User>(); var users = new List<User>();
for (var i = 0; i < numberOfEntities; i++) for (var i = 0; i < numberOfEntities; i++)
...@@ -177,11 +234,11 @@ public async Task GetAllAsync() ...@@ -177,11 +234,11 @@ public async Task GetAllAsync()
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>(); await connection.DeleteAllAsync<User>();
var total = await connection.InsertAsync( users); var total = await connection.InsertAsync(users);
total.IsEqualTo(numberOfEntities); total.IsEqualTo(numberOfEntities);
users = (List<User>) await connection.GetAllAsync<User>(); users = (List<User>)await connection.GetAllAsync<User>();
users.Count.IsEqualTo(numberOfEntities); users.Count.IsEqualTo(numberOfEntities);
var iusers = await connection.GetAllAsync<IUser>(); var iusers = await connection.GetAllAsync<IUser>();
iusers.ToList().Count.IsEqualTo(numberOfEntities); iusers.ToList().Count.IsEqualTo(numberOfEntities);
...@@ -192,8 +249,8 @@ public async Task InsertFieldWithReservedNameAsync() ...@@ -192,8 +249,8 @@ public async Task InsertFieldWithReservedNameAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>(); await connection.DeleteAllAsync<User>();
var id = await connection.InsertAsync(new Result() { Name = "Adam", Order = 1 }); var id = await connection.InsertAsync(new Result { Name = "Adam", Order = 1 });
var result = await connection.GetAsync<Result>(id); var result = await connection.GetAsync<Result>(id);
result.Order.IsEqualTo(1); result.Order.IsEqualTo(1);
...@@ -204,13 +261,14 @@ public async Task DeleteAllAsync() ...@@ -204,13 +261,14 @@ public async Task DeleteAllAsync()
{ {
using (var connection = GetOpenConnection()) using (var connection = GetOpenConnection())
{ {
connection.DeleteAll<User>(); await connection.DeleteAllAsync<User>();
var id1 = await connection.InsertAsync(new User() { Name = "Alice", Age = 32 });
var id2 = await connection.InsertAsync(new User() { Name = "Bob", Age = 33 }); var id1 = await connection.InsertAsync(new User { Name = "Alice", Age = 32 });
var id2 = await connection.InsertAsync(new User { Name = "Bob", Age = 33 });
await connection.DeleteAllAsync<User>(); await connection.DeleteAllAsync<User>();
(await connection.GetAsync<User>(id1)).IsNull(); (await connection.GetAsync<User>(id1)).IsNull();
(await connection.GetAsync<User>(id2)).IsNull(); (await connection.GetAsync<User>(id2)).IsNull();
} }
} }
} }
} }
\ No newline at end of file
...@@ -2,15 +2,17 @@ ...@@ -2,15 +2,17 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata> <metadata>
<id>Dapper.Contrib</id> <id>Dapper.Contrib</id>
<version>1.40</version> <version>1.41</version>
<authors>Sam Saffron,Johan Danforth</authors> <authors>Sam Saffron,Johan Danforth</authors>
<owners>Sam Saffron,Johan Danforth</owners> <owners>Johan Danforth, Marc Gravell</owners>
<licenseUrl>http://www.apache.org/licenses/LICENSE-2.0</licenseUrl> <licenseUrl>http://www.apache.org/licenses/LICENSE-2.0</licenseUrl>
<projectUrl>http://code.google.com/p/dapper-dot-net/</projectUrl> <projectUrl>https://github.com/StackExchange/dapper-dot-net</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>A collection of create,insert,update,delete helpers for dapper.net</description> <description>The official collection of get, insert, update and delete helpers for dapper.net. Also handles lists of entities and optional "dirty" tracking of interface-based entities.</description>
<tags>orm sql micro-orm</tags> <tags>orm sql micro-orm dapper</tags>
<releaseNotes> <releaseNotes>
* 1.42 - InsertAsync() UpdateAsync() and DeleteAsync() now also handles lists of entities (.NET 4.5 only)
* 1.41 - added GetAll(). Insert() Update() and Delete() now handles lists of entities!
* 1.40 - cumulative changes up to dapper 1.40; will track changes more carefully subsequently * 1.40 - cumulative changes up to dapper 1.40; will track changes more carefully subsequently
</releaseNotes> </releaseNotes>
<dependencies> <dependencies>
......
...@@ -93,3 +93,4 @@ Dapper.Contrib makes use of some optional attributes: ...@@ -93,3 +93,4 @@ Dapper.Contrib makes use of some optional attributes:
* Key - this property is the identity/key (unless it is named "Id") * Key - this property is the identity/key (unless it is named "Id")
* Write(true/false) - this property is (not) writeable * Write(true/false) - this property is (not) writeable
* Computed - this property is computed and should not be part of updates * Computed - this property is computed and should not be part of updates
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment