Skip to content

Commit 639ac54

Browse files
committed
feat: implements IQueryableValuesEnabledDbContext
1 parent 2f09565 commit 639ac54

File tree

6 files changed

+264
-4
lines changed

6 files changed

+264
-4
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#if EFCORE
2+
using Microsoft.EntityFrameworkCore;
3+
4+
namespace BlazarTech.QueryableValues
5+
{
6+
/// <summary>
7+
/// Makes the <see cref="QueryableValuesDbContextExtensions"/> available on the type implementing this interface.
8+
/// </summary>
9+
/// <remarks>
10+
/// Useful when your <see cref="DbContext"/> is behind an interface.
11+
/// You can implement <see cref="IQueryableValuesEnabledDbContext"/> on that interface to make the <see cref="QueryableValuesDbContextExtensions"/> available on it.
12+
/// </remarks>
13+
public interface IQueryableValuesEnabledDbContext
14+
{
15+
}
16+
}
17+
#endif
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
#if EFCORE
2+
using BlazarTech.QueryableValues.Builders;
3+
using Microsoft.EntityFrameworkCore;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
8+
namespace BlazarTech.QueryableValues
9+
{
10+
/// <summary>
11+
/// Extension methods provided by QueryableValues on the <see cref="IQueryableValuesEnabledDbContext"/> interface.
12+
/// </summary>
13+
public static class QueryableValuesEnabledDbContextExtensions
14+
{
15+
private static DbContext GetDbContext(IQueryableValuesEnabledDbContext dbContext)
16+
{
17+
if (dbContext is null)
18+
{
19+
throw new ArgumentNullException(nameof(dbContext));
20+
}
21+
22+
if (dbContext is DbContext castedDbContext)
23+
{
24+
return castedDbContext;
25+
}
26+
else
27+
{
28+
throw new InvalidOperationException("QueryableValues only works on a Microsoft.EntityFrameworkCore.DbContext type.");
29+
}
30+
}
31+
32+
/// <summary>
33+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{byte})"/>
34+
/// </summary>
35+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{byte})" path="/param[@name='dbContext']"/></param>
36+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{byte})" path="/param[@name='values']"/></param>
37+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{byte})"/></returns>
38+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{byte})"/></remarks>
39+
/// <exception cref="ArgumentNullException"></exception>
40+
/// <exception cref="InvalidOperationException"></exception>
41+
public static IQueryable<byte> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<byte> values)
42+
{
43+
return GetDbContext(dbContext).AsQueryableValues(values);
44+
}
45+
46+
/// <summary>
47+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{short})"/>
48+
/// </summary>
49+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{short})" path="/param[@name='dbContext']"/></param>
50+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{short})" path="/param[@name='values']"/></param>
51+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{short})"/></returns>
52+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{short})"/></remarks>
53+
/// <exception cref="ArgumentNullException"></exception>
54+
/// <exception cref="InvalidOperationException"></exception>
55+
public static IQueryable<short> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<short> values)
56+
{
57+
return GetDbContext(dbContext).AsQueryableValues(values);
58+
}
59+
60+
/// <summary>
61+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{int})"/>
62+
/// </summary>
63+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{int})" path="/param[@name='dbContext']"/></param>
64+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{int})" path="/param[@name='values']"/></param>
65+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{int})"/></returns>
66+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{int})"/></remarks>
67+
/// <exception cref="ArgumentNullException"></exception>
68+
/// <exception cref="InvalidOperationException"></exception>
69+
public static IQueryable<int> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<int> values)
70+
{
71+
return GetDbContext(dbContext).AsQueryableValues(values);
72+
}
73+
74+
/// <summary>
75+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{long})"/>
76+
/// </summary>
77+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{long})" path="/param[@name='dbContext']"/></param>
78+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{long})" path="/param[@name='values']"/></param>
79+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{long})"/></returns>
80+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{long})"/></remarks>
81+
/// <exception cref="ArgumentNullException"></exception>
82+
/// <exception cref="InvalidOperationException"></exception>
83+
public static IQueryable<long> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<long> values)
84+
{
85+
return GetDbContext(dbContext).AsQueryableValues(values);
86+
}
87+
88+
/// <summary>
89+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{decimal}, int)"/>
90+
/// </summary>
91+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{decimal}, int)" path="/param[@name='dbContext']"/></param>
92+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{decimal}, int)" path="/param[@name='values']"/></param>
93+
/// <param name="numberOfDecimals"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{decimal}, int)" path="/param[@name='numberOfDecimals']"/></param>
94+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{decimal}, int)"/></returns>
95+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{decimal}, int)"/></remarks>
96+
/// <exception cref="ArgumentNullException"></exception>
97+
/// <exception cref="InvalidOperationException"></exception>
98+
public static IQueryable<decimal> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<decimal> values, int numberOfDecimals = 4)
99+
{
100+
return GetDbContext(dbContext).AsQueryableValues(values, numberOfDecimals);
101+
}
102+
103+
/// <summary>
104+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{float})"/>
105+
/// </summary>
106+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{float})" path="/param[@name='dbContext']"/></param>
107+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{float})" path="/param[@name='values']"/></param>
108+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{float})"/></returns>
109+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{float})"/></remarks>
110+
/// <exception cref="ArgumentNullException"></exception>
111+
/// <exception cref="InvalidOperationException"></exception>
112+
public static IQueryable<float> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<float> values)
113+
{
114+
return GetDbContext(dbContext).AsQueryableValues(values);
115+
}
116+
117+
/// <summary>
118+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{double})"/>
119+
/// </summary>
120+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{double})" path="/param[@name='dbContext']"/></param>
121+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{double})" path="/param[@name='values']"/></param>
122+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{double})"/></returns>
123+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{double})"/></remarks>
124+
/// <exception cref="ArgumentNullException"></exception>
125+
/// <exception cref="InvalidOperationException"></exception>
126+
public static IQueryable<double> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<double> values)
127+
{
128+
return GetDbContext(dbContext).AsQueryableValues(values);
129+
}
130+
131+
/// <summary>
132+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{DateTime})"/>
133+
/// </summary>
134+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{DateTime})" path="/param[@name='dbContext']"/></param>
135+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{DateTime})" path="/param[@name='values']"/></param>
136+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{DateTime})"/></returns>
137+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{DateTime})"/></remarks>
138+
/// <exception cref="ArgumentNullException"></exception>
139+
/// <exception cref="InvalidOperationException"></exception>
140+
public static IQueryable<DateTime> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<DateTime> values)
141+
{
142+
return GetDbContext(dbContext).AsQueryableValues(values);
143+
}
144+
145+
/// <summary>
146+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{DateTimeOffset})"/>
147+
/// </summary>
148+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{DateTimeOffset})" path="/param[@name='dbContext']"/></param>
149+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{DateTimeOffset})" path="/param[@name='values']"/></param>
150+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{DateTimeOffset})"/></returns>
151+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{DateTimeOffset})"/></remarks>
152+
/// <exception cref="ArgumentNullException"></exception>
153+
/// <exception cref="InvalidOperationException"></exception>
154+
public static IQueryable<DateTimeOffset> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<DateTimeOffset> values)
155+
{
156+
return GetDbContext(dbContext).AsQueryableValues(values);
157+
}
158+
159+
/// <summary>
160+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{char}, bool)"/>
161+
/// </summary>
162+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{char}, bool)" path="/param[@name='dbContext']"/></param>
163+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{char}, bool)" path="/param[@name='values']"/></param>
164+
/// <param name="isUnicode"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{char}, bool)" path="/param[@name='isUnicode']"/></param>
165+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{char}, bool)"/></returns>
166+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{char}, bool)"/></remarks>
167+
/// <exception cref="ArgumentNullException"></exception>
168+
/// <exception cref="InvalidOperationException"></exception>
169+
public static IQueryable<char> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<char> values, bool isUnicode = false)
170+
{
171+
return GetDbContext(dbContext).AsQueryableValues(values, isUnicode: isUnicode);
172+
}
173+
174+
/// <summary>
175+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{string}, bool)"/>
176+
/// </summary>
177+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{string}, bool)" path="/param[@name='dbContext']"/></param>
178+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{string}, bool)" path="/param[@name='values']"/></param>
179+
/// <param name="isUnicode"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{string}, bool)" path="/param[@name='isUnicode']"/></param>
180+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{string}, bool)"/></returns>
181+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{string}, bool)"/></remarks>
182+
/// <exception cref="ArgumentNullException"></exception>
183+
/// <exception cref="InvalidOperationException"></exception>
184+
public static IQueryable<string> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<string> values, bool isUnicode = false)
185+
{
186+
return GetDbContext(dbContext).AsQueryableValues(values, isUnicode: isUnicode);
187+
}
188+
189+
/// <summary>
190+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{Guid})"/>
191+
/// </summary>
192+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{Guid})" path="/param[@name='dbContext']"/></param>
193+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{Guid})" path="/param[@name='values']"/></param>
194+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{Guid})"/></returns>
195+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues(DbContext, IEnumerable{Guid})"/></remarks>
196+
/// <exception cref="ArgumentNullException"></exception>
197+
/// <exception cref="InvalidOperationException"></exception>
198+
public static IQueryable<Guid> AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<Guid> values)
199+
{
200+
return GetDbContext(dbContext).AsQueryableValues(values);
201+
}
202+
203+
/// <summary>
204+
/// <inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues{TSource}(DbContext, IEnumerable{TSource}, Action{EntityOptionsBuilder{TSource}}?)"/>
205+
/// </summary>
206+
/// <param name="dbContext"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues{TSource}(DbContext, IEnumerable{TSource}, Action{EntityOptionsBuilder{TSource}}?)" path="/param[@name='dbContext']"/></param>
207+
/// <param name="values"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues{TSource}(DbContext, IEnumerable{TSource}, Action{EntityOptionsBuilder{TSource}}?)" path="/param[@name='values']"/></param>
208+
/// <param name="configure"><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues{TSource}(DbContext, IEnumerable{TSource}, Action{EntityOptionsBuilder{TSource}}?)" path="/param[@name='configure']"/></param>
209+
/// <returns><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues{TSource}(DbContext, IEnumerable{TSource}, Action{EntityOptionsBuilder{TSource}}?)"/></returns>
210+
/// <remarks><inheritdoc cref="QueryableValuesDbContextExtensions.AsQueryableValues{TSource}(DbContext, IEnumerable{TSource}, Action{EntityOptionsBuilder{TSource}}?)"/></remarks>
211+
/// <exception cref="ArgumentNullException"></exception>
212+
/// <exception cref="InvalidOperationException"></exception>
213+
public static IQueryable<TSource> AsQueryableValues<TSource>(this IQueryableValuesEnabledDbContext dbContext, IEnumerable<TSource> values, Action<EntityOptionsBuilder<TSource>>? configure = null)
214+
where TSource : notnull
215+
{
216+
return GetDbContext(dbContext).AsQueryableValues(values, configure);
217+
}
218+
}
219+
}
220+
#endif

tests/QueryableValues.SqlServer.Tests/Integration/ComplexTypeTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace BlazarTech.QueryableValues.SqlServer.Tests.Integration
1111
[Collection("DbContext")]
1212
public class ComplexTypeTests
1313
{
14-
private readonly MyDbContext _db;
14+
private readonly IMyDbContext _db;
1515

1616
public class TestType
1717
{

tests/QueryableValues.SqlServer.Tests/Integration/InfrastructureTests.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Linq;
7-
using System.Text;
87
using System.Text.RegularExpressions;
98
using System.Threading.Tasks;
109
using Xunit;
@@ -41,6 +40,19 @@ public void MustNotScriptOutInternalEntity()
4140
Assert.DoesNotContain("QueryableValues", script, StringComparison.OrdinalIgnoreCase);
4241
}
4342

43+
[Fact]
44+
public void OnlyWorksOnDbContext()
45+
{
46+
var db = new NotADbContext();
47+
48+
var exception = Assert.Throws<InvalidOperationException>(() =>
49+
{
50+
_ = db.AsQueryableValues(new[] { 1 }).ToList();
51+
});
52+
53+
Assert.Contains("QueryableValues only works on a Microsoft.EntityFrameworkCore.DbContext type.", exception.Message);
54+
}
55+
4456
#if !EFCORE3
4557
[Fact]
4658
public async Task MustControlSelectTopOptimization()
@@ -87,5 +99,9 @@ async Task<bool> isOptimizationEnabledComplexType(MyDbContextBase db)
8799
}
88100
#endif
89101
}
102+
103+
class NotADbContext : IQueryableValuesEnabledDbContext
104+
{
105+
}
90106
}
91107
#endif

0 commit comments

Comments
 (0)