Releases: chunty/Simpository
2.0.1
2.0.0
The .net 10 update!
What's New
- Multi-targeting — Simpository now targets
net8.0,net9.0, andnet10.0 AsAsyncEnumerable()— new method onIReadRepository<T>for explicit async enumeration
Breaking Changes
1. IAsyncEnumerable<T> removed from IReadRepository<T>
IReadRepository<T> no longer inherits from IAsyncEnumerable<T>. This was required to resolve a compiler
ambiguity (CS0121) introduced in .NET 10, where the BCL added System.Linq.AsyncEnumerable extension methods that
clashed with EF Core's LINQ extensions on types implementing both IQueryable<T> and IAsyncEnumerable<T>.
See: https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/10.0/asyncenumerable
Before:
await foreach (var item in repository)
{
// ...
}After:
await foreach (var item in repository.AsAsyncEnumerable())
{
// ...
}2. Custom IReadRepository<T> implementations must add AsAsyncEnumerable()
If you have a custom class that implements IReadRepository<T> directly, you must implement the new method:
public IAsyncEnumerable<T> AsAsyncEnumerable() => this;If your class does not implement
IAsyncEnumerable<T>, delegate to your underlying queryable instead:public IAsyncEnumerable<T> AsAsyncEnumerable() => _dbSet.AsAsyncEnumerable();
Migration Guide
| Scenario | Before | After |
|---|---|---|
await foreach via interface |
await foreach (var x in repo) |
await foreach (var x in repo.AsAsyncEnumerable()) |
await foreach via concrete type |
await foreach (var x in repo) |
✅ No change needed |
ToListAsync() |
await repo.ToListAsync() |
✅ No change needed |
Where(), FirstOrDefaultAsync(), etc. |
repo.Where(...) |
✅ No change needed |
Custom IReadRepository<T> impl |
N/A | Add AsAsyncEnumerable() |
v1.1.0
Breaking Changes
IReadRepository<T>has two new methods —Get(object[] keys)andGetOrThrow(object[] keys). Custom
implementations of the interface must add these methods. Repos that extendReadRepository<T, TContext>are
unaffected.DataNotFoundExceptionmessage format changed — If you match on exception message strings, update to the new
format.
What's New
Composite key support for Get and GetOrThrow
IReadRepository<T> now has Get(object[] keys) and GetOrThrow(object[] keys) overloads, enabling direct
database queries on entities with composite primary keys.
var line = await repo.GetOrThrow(new object[] { orderId, lineNumber });Clearer errors for composite keys
Calling the single-key Get(object) or GetOrThrow(object) on a composite-key entity now throws a
NotSupportedException with a message pointing to the correct overload, instead of silently querying only the first
key column.
Improvements
- Exception messages —
DataNotFoundExceptionmessages are now more readable:"OrderLine not found with OrderId, LineNumber: 1, 2"instead of the previous awkward format. - Internal cleanup — Shared reflection logic in
AddGenericReadRepo/AddGenericWriteRepoextracted to a
private helper, removing duplication.