Skip to content

Commit 332f488

Browse files
author
Jeff Treuting
committed
GetMany and GetManyAsDictionary
Fixes #112
1 parent 9420ab2 commit 332f488

6 files changed

Lines changed: 205 additions & 2 deletions

File tree

SharpRepository.RavenDbRepository/RavenDbRepositoryBase.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Linq.Expressions;
45
using Raven.Client;
@@ -71,6 +72,36 @@ protected override T GetQuery(TKey key)
7172
return base.GetQuery(key);
7273
}
7374

75+
public override IEnumerable<T> GetMany(params TKey[] keys)
76+
{
77+
return GetMany(keys.ToList());
78+
}
79+
80+
public override IEnumerable<T> GetMany(IEnumerable<TKey> keys)
81+
{
82+
return keys.Select(Get);
83+
}
84+
85+
public override IEnumerable<TResult> GetMany<TResult>(Expression<Func<T, TResult>> selector, params TKey[] keys)
86+
{
87+
return GetMany(keys.ToList(), selector);
88+
}
89+
90+
public override IEnumerable<TResult> GetMany<TResult>(IEnumerable<TKey> keys, Expression<Func<T, TResult>> selector)
91+
{
92+
return keys.Select(x => Get(x, selector));
93+
}
94+
95+
public override IDictionary<TKey, T> GetManyAsDictionary(params TKey[] keys)
96+
{
97+
return GetManyAsDictionary(keys.ToList());
98+
}
99+
100+
public override IDictionary<TKey, T> GetManyAsDictionary(IEnumerable<TKey> keys)
101+
{
102+
return GetMany(keys).ToDictionary(GetPrimaryKey);
103+
}
104+
74105
public override TResult Min<TResult>(ISpecification<T> criteria, Expression<Func<T, TResult>> selector)
75106
{
76107
var pagingOptions = new PagingOptions<T, TResult>(1, 1, selector);

SharpRepository.Repository/ConfigurationBasedRepository.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,36 @@ public TResult Get<TResult>(TKey key, Expression<Func<T, TResult>> selector)
189189
return Repository.Get(key, selector);
190190
}
191191

192+
public IEnumerable<T> GetMany(params TKey[] keys)
193+
{
194+
return Repository.GetMany(keys);
195+
}
196+
197+
public IEnumerable<T> GetMany(IEnumerable<TKey> keys)
198+
{
199+
return Repository.GetMany(keys);
200+
}
201+
202+
public IEnumerable<TResult> GetMany<TResult>(Expression<Func<T, TResult>> selector, params TKey[] keys)
203+
{
204+
return Repository.GetMany(selector, keys);
205+
}
206+
207+
public IEnumerable<TResult> GetMany<TResult>(IEnumerable<TKey> keys, Expression<Func<T, TResult>> selector)
208+
{
209+
return Repository.GetMany(keys, selector);
210+
}
211+
212+
public IDictionary<TKey, T> GetManyAsDictionary(params TKey[] keys)
213+
{
214+
return Repository.GetManyAsDictionary(keys);
215+
}
216+
217+
public IDictionary<TKey, T> GetManyAsDictionary(IEnumerable<TKey> keys)
218+
{
219+
return Repository.GetManyAsDictionary(keys);
220+
}
221+
192222
public bool Exists(TKey key)
193223
{
194224
T entity;

SharpRepository.Repository/ICrudRepository.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,28 @@ public interface ICrudRepository<T, TKey> : IRepositoryBase<T> where T : class
3535
/// <returns>The mapped entity based on the selector that matches on the primary key.</returns>
3636
TResult Get<TResult>(TKey key, Expression<Func<T, TResult>> selector);
3737

38+
/// <summary>
39+
/// Gets the specified entity of type <typeparamref name="T"/> from the repository by the primary key.
40+
/// </summary>
41+
/// <param name="keys">The primary keys.</param>
42+
/// <returns>The entity that matches on the primary key</returns>
43+
IEnumerable<T> GetMany(params TKey[] keys);
44+
45+
/// <summary>
46+
/// Gets the specified entity of type <typeparamref name="T"/> from the repository by the primary key.
47+
/// </summary>
48+
/// <param name="keys">The primary keys.</param>
49+
/// <returns>The entity that matches on the primary key</returns>
50+
IEnumerable<T> GetMany(IEnumerable<TKey> keys);
51+
52+
IEnumerable<TResult> GetMany<TResult>(Expression<Func<T, TResult>> selector, params TKey[] keys);
53+
54+
IEnumerable<TResult> GetMany<TResult>(IEnumerable<TKey> keys, Expression<Func<T, TResult>> selector);
55+
56+
IDictionary<TKey, T> GetManyAsDictionary(params TKey[] keys);
57+
58+
IDictionary<TKey, T> GetManyAsDictionary(IEnumerable<TKey> keys);
59+
3860
/// <summary>
3961
/// Returns true if the specified entity of type <typeparamref name="T"/> from the repository by the primary key exists
4062
/// </summary>

SharpRepository.Repository/RepositoryBase.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,36 @@ public TResult Get<TResult>(TKey key, Expression<Func<T, TResult>> selector)
262262
}
263263
}
264264

265+
public virtual IEnumerable<T> GetMany(params TKey[] keys)
266+
{
267+
return GetMany(keys.ToList());
268+
}
269+
270+
public virtual IEnumerable<T> GetMany(IEnumerable<TKey> keys)
271+
{
272+
return FindAll(ByMultipleKeysSpecification(keys));
273+
}
274+
275+
public virtual IEnumerable<TResult> GetMany<TResult>(Expression<Func<T, TResult>> selector, params TKey[] keys)
276+
{
277+
return GetMany(keys.ToList(), selector);
278+
}
279+
280+
public virtual IEnumerable<TResult> GetMany<TResult>(IEnumerable<TKey> keys, Expression<Func<T, TResult>> selector)
281+
{
282+
return FindAll(ByMultipleKeysSpecification(keys), selector);
283+
}
284+
285+
public virtual IDictionary<TKey, T> GetManyAsDictionary(params TKey[] keys)
286+
{
287+
return GetManyAsDictionary(keys.ToList());
288+
}
289+
290+
public virtual IDictionary<TKey, T> GetManyAsDictionary(IEnumerable<TKey> keys)
291+
{
292+
return GetMany(keys).ToDictionary(GetPrimaryKey);
293+
}
294+
265295
public bool Exists(TKey key)
266296
{
267297
T entity;
@@ -1426,6 +1456,27 @@ protected virtual ISpecification<T> ByPrimaryKeySpecification(TKey key)
14261456
return new Specification<T>(lambda);
14271457
}
14281458

1459+
protected virtual ISpecification<T> ByMultipleKeysSpecification(IEnumerable<TKey> keys)
1460+
{
1461+
var propInfo = GetPrimaryKeyPropertyInfo();
1462+
if (propInfo == null || keys == null)
1463+
return null;
1464+
1465+
var parameter = Expression.Parameter(typeof(T), "x");
1466+
1467+
return keys.Select(key =>
1468+
Expression.Lambda<Func<T, bool>>(
1469+
Expression.Equal(
1470+
Expression.PropertyOrField(parameter, propInfo.Name),
1471+
Expression.Constant(key)
1472+
), parameter
1473+
)
1474+
)
1475+
.Aggregate<Expression<Func<T, bool>>, ISpecification<T>>(null,
1476+
(current, lambda) => current == null ? new Specification<T>(lambda) : current.Or(lambda)
1477+
);
1478+
}
1479+
14291480
protected virtual PropertyInfo GetPrimaryKeyPropertyInfo()
14301481
{
14311482
// checks for properties in this order that match TKey type

SharpRepository.Repository/Traits/ICanGet.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,18 @@ namespace SharpRepository.Repository.Traits
1313
/// </summary>
1414
/// <typeparam name="T">Generic repository entity type</typeparam>
1515
/// <typeparam name="TKey">Generic repository entity key type</typeparam>
16-
public interface ICanGet<T, in TKey>
16+
public interface ICanGet<T, TKey>
1717
{
1818
T Get(TKey key);
1919
TResult Get<TResult>(TKey key, Expression<Func<T, TResult>> selector);
2020

21+
IEnumerable<T> GetMany(params TKey[] keys);
22+
IEnumerable<T> GetMany(IEnumerable<TKey> keys);
23+
IEnumerable<TResult> GetMany<TResult>(Expression<Func<T, TResult>> selector, params TKey[] keys);
24+
IEnumerable<TResult> GetMany<TResult>(IEnumerable<TKey> keys, Expression<Func<T, TResult>> selector);
25+
IDictionary<TKey, T> GetManyAsDictionary(params TKey[] keys);
26+
IDictionary<TKey, T> GetManyAsDictionary(IEnumerable<TKey> keys);
27+
2128
bool Exists(TKey key);
2229
bool TryGet(TKey key, out T entity);
2330
bool TryGet<TResult>(TKey key, Expression<Func<T, TResult>> selector, out TResult entity);

SharpRepository.Tests.Integration/RepositoryGetTests.cs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Linq;
12
using NUnit.Framework;
23
using SharpRepository.Repository;
34
using SharpRepository.Tests.Integration.TestAttributes;
@@ -109,9 +110,70 @@ public void TryGet_Should_Return_True_If_Item_Exists(IRepository<Contact, string
109110
}
110111

111112
[ExecuteForAllRepositories]
112-
public void TryGet_Should_Return_Falsel_If_Item_Does_Not_Exists(IRepository<Contact, string> repository)
113+
public void TryGet_Should_Return_False_If_Item_Does_Not_Exists(IRepository<Contact, string> repository)
113114
{
114115
repository.Exists(string.Empty).ShouldBeFalse();
115116
}
117+
118+
[ExecuteForAllRepositories]
119+
public void GetMany_Params_Should_Return_Multiple_Items(IRepository<Contact, string> repository)
120+
{
121+
for (var i = 1; i <= 5; i++)
122+
{
123+
var contact = new Contact { ContactId = i.ToString(), Name = "Test User " + i};
124+
repository.Add(contact);
125+
}
126+
127+
var items = repository.GetMany("1", "3", "4", "5");
128+
items.Count().ShouldEqual(4);
129+
}
130+
131+
[ExecuteForAllRepositories]
132+
public void GetMany_List_Should_Return_Multiple_Items(IRepository<Contact, string> repository)
133+
{
134+
for (var i = 1; i <= 5; i++)
135+
{
136+
var contact = new Contact { ContactId = i.ToString(), Name = "Test User " + i};
137+
repository.Add(contact);
138+
}
139+
140+
var items = repository.GetMany(new [] {"1", "3", "4", "5" }.ToList());
141+
items.Count().ShouldEqual(4);
142+
}
143+
144+
[ExecuteForAllRepositories]
145+
public void GetManyAsDictionary_Params_Should_Return_Multiple_Items(IRepository<Contact, string> repository)
146+
{
147+
for (var i = 1; i <= 5; i++)
148+
{
149+
var contact = new Contact { ContactId = i.ToString(), Name = "Test User " + i};
150+
repository.Add(contact);
151+
}
152+
153+
var items = repository.GetManyAsDictionary("1", "3", "4", "5");
154+
items.Count().ShouldEqual(4);
155+
items.ContainsKey("1").ShouldBeTrue();
156+
items.ContainsKey("2").ShouldBeFalse();
157+
items.ContainsKey("3").ShouldBeTrue();
158+
items.ContainsKey("4").ShouldBeTrue();
159+
items.ContainsKey("5").ShouldBeTrue();
160+
}
161+
162+
[ExecuteForAllRepositories]
163+
public void GetManyAsDictionary_List_Should_Return_Multiple_Items(IRepository<Contact, string> repository)
164+
{
165+
for (var i = 1; i <= 5; i++)
166+
{
167+
var contact = new Contact { ContactId = i.ToString(), Name = "Test User " + i};
168+
repository.Add(contact);
169+
}
170+
171+
var items = repository.GetManyAsDictionary(new [] {"1", "3", "4", "5" }.ToList());
172+
items.ContainsKey("1").ShouldBeTrue();
173+
items.ContainsKey("2").ShouldBeFalse();
174+
items.ContainsKey("3").ShouldBeTrue();
175+
items.ContainsKey("4").ShouldBeTrue();
176+
items.ContainsKey("5").ShouldBeTrue();
177+
}
116178
}
117179
}

0 commit comments

Comments
 (0)