Skip to content

Commit 6f0dea9

Browse files
Merge pull request #14 from johelvisguzman/dev
Merge pull requests from johelvisguzman/dev
2 parents f6a5a89 + 4c8efcf commit 6f0dea9

31 files changed

+3189
-53
lines changed

DotNetToolkit.Repository.sln

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
4-
VisualStudioVersion = 15.0.27004.2006
4+
VisualStudioVersion = 15.0.27130.2003
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}"
77
EndProject
@@ -15,6 +15,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.En
1515
EndProject
1616
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.Integration.Test", "test\DotNetToolkit.Repository.Integration.Test\DotNetToolkit.Repository.Integration.Test.csproj", "{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}"
1717
EndProject
18+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.InMemory", "src\DotNetToolkit.Repository.InMemory\DotNetToolkit.Repository.InMemory.csproj", "{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}"
19+
EndProject
20+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetToolkit.Repository.EntityFrameworkCore", "src\DotNetToolkit.Repository.EntityFrameworkCore\DotNetToolkit.Repository.EntityFrameworkCore.csproj", "{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}"
21+
EndProject
1822
Global
1923
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2024
Debug|Any CPU = Debug|Any CPU
@@ -37,6 +41,14 @@ Global
3741
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
3842
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
3943
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6}.Release|Any CPU.Build.0 = Release|Any CPU
44+
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45+
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}.Debug|Any CPU.Build.0 = Debug|Any CPU
46+
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}.Release|Any CPU.ActiveCfg = Release|Any CPU
47+
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E}.Release|Any CPU.Build.0 = Release|Any CPU
48+
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49+
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}.Debug|Any CPU.Build.0 = Debug|Any CPU
50+
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}.Release|Any CPU.ActiveCfg = Release|Any CPU
51+
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D}.Release|Any CPU.Build.0 = Release|Any CPU
4052
EndGlobalSection
4153
GlobalSection(SolutionProperties) = preSolution
4254
HideSolutionNode = FALSE
@@ -46,6 +58,8 @@ Global
4658
{EAE7B507-D908-4650-A301-C3341F005A51} = {DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}
4759
{8DBCF7DE-532D-45DF-A6B8-5D89415C5B77} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
4860
{2F99B66F-A347-4E8D-8ACA-5A34246A1FA6} = {DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}
61+
{715D2F11-3AAF-476E-9A6A-DCA6DEBD377E} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
62+
{0A9D9AA4-F01C-470F-AD5B-5A81EA7A398D} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
4963
EndGlobalSection
5064
GlobalSection(ExtensibilityGlobals) = postSolution
5165
SolutionGuid = {96973E0C-81D1-42DE-9F78-7103241B4E07}

appveyor.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ build:
4545

4646
after_build:
4747
- dotnet pack .\src\DotNetToolkit.Repository\DotNetToolkit.Repository.csproj --configuration Release
48+
- dotnet pack .\src\DotNetToolkit.Repository.InMemory\DotNetToolkit.Repository.InMemory.csproj --configuration Release
4849
- dotnet pack .\src\DotNetToolkit.Repository.EntityFramework\DotNetToolkit.Repository.EntityFramework.csproj --configuration Release
50+
- dotnet pack .\src\DotNetToolkit.Repository.EntityFrameworkCore\DotNetToolkit.Repository.EntityFrameworkCore.csproj --configuration Release
4951

5052
#---------------------------------#
5153
# tests configuration #

src/DotNetToolkit.Repository.EntityFramework/EfRepositoryBase.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public abstract class EfRepositoryBase<TEntity, TKey> : RepositoryAsyncBase<TEnt
2727
/// <summary>
2828
/// Gets the entity set.
2929
/// </summary>
30-
protected IDbSet<TEntity> DbSet { get; private set; }
30+
protected DbSet<TEntity> DbSet { get; private set; }
3131

3232
/// <summary>
3333
/// Gets the database context.
@@ -153,9 +153,7 @@ public override void Dispose()
153153
/// </summary>
154154
protected override Task<TEntity> GetEntityAsync(TKey key, IFetchStrategy<TEntity> fetchStrategy, CancellationToken cancellationToken = new CancellationToken())
155155
{
156-
var dbSet = (DbSet<TEntity>)DbSet;
157-
158-
return fetchStrategy == null ? dbSet.FindAsync(cancellationToken, key) : base.GetEntityAsync(key, fetchStrategy, cancellationToken);
156+
return fetchStrategy == null ? DbSet.FindAsync(cancellationToken, key) : base.GetEntityAsync(key, fetchStrategy, cancellationToken);
159157
}
160158

161159
/// <summary>

src/DotNetToolkit.Repository.EntityFramework/EfRepositoryFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ private static DbContext GetDbContext(IRepositoryOptions options)
1717

1818
DbContext context;
1919

20-
if (string.IsNullOrEmpty(options.ConnectionString))
20+
if (options.DbContextArgs == null)
2121
context = (DbContext)Activator.CreateInstance(options.DbContextType);
2222
else
23-
context = (DbContext)Activator.CreateInstance(options.DbContextType, options.ConnectionString);
23+
context = (DbContext)Activator.CreateInstance(options.DbContextType, options.DbContextArgs);
2424

2525
return context;
2626
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<Import Project="..\..\build\common.props" />
4+
5+
<PropertyGroup>
6+
<TargetFrameworks>net451;netstandard1.3</TargetFrameworks>
7+
<AssemblyName>DotNetToolkit.Repository.EntityFrameworkCore</AssemblyName>
8+
<RootNamespace>DotNetToolkit.Repository.EntityFrameworkCore</RootNamespace>
9+
<Description>A toolkit that provides a lightweight starter kit for using the Repository pattern for the Entity Framework Core.</Description>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.5" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\DotNetToolkit.Repository\DotNetToolkit.Repository.csproj" />
18+
</ItemGroup>
19+
20+
</Project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
namespace DotNetToolkit.Repository.EntityFrameworkCore
2+
{
3+
using Microsoft.EntityFrameworkCore;
4+
5+
/// <summary>
6+
/// Represents a repository for entity framework core.
7+
/// </summary>
8+
public class EfCoreRepository<TEntity, TKey> : EfCoreRepositoryBase<TEntity, TKey> where TEntity : class
9+
{
10+
#region Constructors
11+
12+
/// <summary>
13+
/// Initializes a new instance of the <see cref="EfCoreRepository{TEntity, TKey}" /> class.
14+
/// </summary>
15+
/// <param name="context">The database context.</param>
16+
public EfCoreRepository(DbContext context) : base(context) { }
17+
18+
#endregion
19+
}
20+
21+
/// <summary>
22+
/// Represents a repository for entity framework core with a default primary key value of type integer.
23+
/// </summary>
24+
public class EfCoreRepository<TEntity> : EfCoreRepositoryBase<TEntity, int>, IRepository<TEntity> where TEntity : class
25+
{
26+
#region Constructors
27+
28+
/// <summary>
29+
/// Initializes a new instance of the <see cref="EfCoreRepository{TEntity}" /> class.
30+
/// </summary>
31+
/// <param name="context">The database context.</param>
32+
public EfCoreRepository(DbContext context) : base(context) { }
33+
34+
#endregion
35+
}
36+
}
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
namespace DotNetToolkit.Repository.EntityFrameworkCore
2+
{
3+
using FetchStrategies;
4+
using Microsoft.EntityFrameworkCore;
5+
using Queries;
6+
using Specifications;
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Linq;
10+
using System.Linq.Expressions;
11+
using System.Threading;
12+
using System.Threading.Tasks;
13+
14+
/// <summary>
15+
/// Represents a repository for entity framework core.
16+
/// </summary>
17+
public abstract class EfCoreRepositoryBase<TEntity, TKey> : RepositoryAsyncBase<TEntity, TKey> where TEntity : class
18+
{
19+
#region Fields
20+
21+
private bool _disposed;
22+
23+
#endregion
24+
25+
#region Properties
26+
27+
/// <summary>
28+
/// Gets the entity set.
29+
/// </summary>
30+
protected DbSet<TEntity> DbSet { get; private set; }
31+
32+
/// <summary>
33+
/// Gets the database context.
34+
/// </summary>
35+
protected DbContext Context { get; private set; }
36+
37+
#endregion
38+
39+
#region Constructors
40+
41+
/// <summary>
42+
/// Initializes a new instance of the <see cref="EfCoreRepositoryBase{TEntity, TKey}" /> class.
43+
/// </summary>
44+
/// <param name="context">The database context.</param>
45+
protected EfCoreRepositoryBase(DbContext context)
46+
{
47+
if (context == null)
48+
throw new ArgumentNullException(nameof(context));
49+
50+
Context = context;
51+
DbSet = Context.Set<TEntity>();
52+
}
53+
54+
#endregion
55+
56+
#region Protected Methods
57+
58+
/// <summary>
59+
/// Releases unmanaged and - optionally - managed resources.
60+
/// </summary>
61+
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
62+
protected virtual void Dispose(bool disposing)
63+
{
64+
if (_disposed) return;
65+
66+
if (disposing)
67+
{
68+
if (Context != null)
69+
{
70+
Context.Dispose();
71+
}
72+
}
73+
74+
_disposed = true;
75+
}
76+
77+
#endregion
78+
79+
#region Overrides of RepositoryBase<TEntity,TKey>
80+
81+
/// <summary>
82+
/// A protected overridable method for adding the specified <paramref name="entity" /> into the repository.
83+
/// </summary>
84+
protected override void AddItem(TEntity entity)
85+
{
86+
DbSet.Add(entity);
87+
}
88+
89+
/// <summary>
90+
/// A protected overridable method for deleting the specified <paramref name="entity" /> from the repository.
91+
/// </summary>
92+
protected override void DeleteItem(TEntity entity)
93+
{
94+
DbSet.Remove(entity);
95+
}
96+
97+
/// <summary>
98+
/// A protected overridable method for updating the specified <paramref name="entity" /> in the repository.
99+
/// </summary>
100+
protected override void UpdateItem(TEntity entity)
101+
{
102+
Context.Entry(entity).State = EntityState.Modified;
103+
}
104+
105+
/// <summary>
106+
/// A protected overridable method for saving changes made in the current unit of work in the repository.
107+
/// </summary>
108+
protected override void SaveChanges()
109+
{
110+
Context.SaveChanges();
111+
}
112+
113+
/// <summary>
114+
/// A protected overridable method for getting an entity query that supplies the specified fetching strategy from the repository.
115+
/// </summary>
116+
protected override IQueryable<TEntity> GetQuery(IFetchStrategy<TEntity> fetchStrategy = null)
117+
{
118+
var query = DbSet.AsQueryable();
119+
return fetchStrategy == null ? query : fetchStrategy.IncludePaths.Aggregate(query, (current, path) => current.Include(path));
120+
}
121+
122+
/// <summary>
123+
/// Gets an entity query with the given primary key value from the repository.
124+
/// </summary>
125+
protected override TEntity GetEntity(TKey key, IFetchStrategy<TEntity> fetchStrategy)
126+
{
127+
return fetchStrategy == null ? DbSet.Find(key) : base.GetEntity(key, fetchStrategy);
128+
}
129+
130+
/// <summary>
131+
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
132+
/// </summary>
133+
public override void Dispose()
134+
{
135+
Dispose(true);
136+
GC.SuppressFinalize(this);
137+
}
138+
139+
#endregion
140+
141+
#region Overrides of RepositoryAsyncBase<TEntity,TKey>
142+
143+
/// <summary>
144+
/// A protected asynchronous overridable method for saving changes made in the current unit of work in the repository.
145+
/// </summary>
146+
protected override Task SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
147+
{
148+
return Context.SaveChangesAsync(cancellationToken);
149+
}
150+
151+
/// <summary>
152+
/// Gets an entity query with the given primary key value from the repository.
153+
/// </summary>
154+
protected override Task<TEntity> GetEntityAsync(TKey key, IFetchStrategy<TEntity> fetchStrategy, CancellationToken cancellationToken = new CancellationToken())
155+
{
156+
return fetchStrategy == null ? DbSet.FindAsync(new object[] { key }, cancellationToken) : base.GetEntityAsync(key, fetchStrategy, cancellationToken);
157+
}
158+
159+
/// <summary>
160+
/// A protected asynchronous overridable method for getting an entity that satisfies the criteria specified by the <paramref name="criteria" /> from the repository.
161+
/// </summary>
162+
protected override Task<TEntity> GetEntityAsync(ISpecification<TEntity> criteria, IQueryOptions<TEntity> options, CancellationToken cancellationToken = new CancellationToken())
163+
{
164+
if (criteria == null)
165+
throw new ArgumentNullException(nameof(criteria));
166+
167+
return GetQuery(criteria, options).FirstOrDefaultAsync(cancellationToken);
168+
}
169+
170+
/// <summary>
171+
/// A protected asynchronous overridable method for getting an entity that satisfies the criteria specified by the <paramref name="criteria" /> from the repository.
172+
/// </summary>
173+
protected override Task<TResult> GetEntityAsync<TResult>(ISpecification<TEntity> criteria, IQueryOptions<TEntity> options, Expression<Func<TEntity, TResult>> selector, CancellationToken cancellationToken = new CancellationToken())
174+
{
175+
if (criteria == null)
176+
throw new ArgumentNullException(nameof(criteria));
177+
178+
return GetQuery(criteria, options).Select(selector).FirstOrDefaultAsync(cancellationToken);
179+
}
180+
181+
/// <summary>
182+
/// A protected asynchronous overridable method for getting a collection of entities that satisfies the criteria specified by the <paramref name="criteria" /> from the repository.
183+
/// </summary>
184+
protected override Task<List<TEntity>> GetEntitiesAsync(ISpecification<TEntity> criteria, IQueryOptions<TEntity> options, CancellationToken cancellationToken = new CancellationToken())
185+
{
186+
if (criteria == null)
187+
throw new ArgumentNullException(nameof(criteria));
188+
189+
return GetQuery(criteria, options).ToListAsync(cancellationToken);
190+
}
191+
192+
/// <summary>
193+
/// A protected asynchronous overridable method for getting a collection of entities that satisfies the criteria specified by the <paramref name="criteria" /> from the repository.
194+
/// </summary>
195+
protected override Task<List<TResult>> GetEntitiesAsync<TResult>(ISpecification<TEntity> criteria, IQueryOptions<TEntity> options, Expression<Func<TEntity, TResult>> selector, CancellationToken cancellationToken = new CancellationToken())
196+
{
197+
if (criteria == null)
198+
throw new ArgumentNullException(nameof(criteria));
199+
200+
return GetQuery(criteria, options).Select(selector).ToListAsync(cancellationToken);
201+
}
202+
203+
/// <summary>
204+
/// A protected asynchronous overridable method for getting a the number of entities that satisfies the criteria specified by the <paramref name="criteria" /> from the repository.
205+
/// </summary>
206+
protected override Task<int> GetCountAsync(ISpecification<TEntity> criteria, CancellationToken cancellationToken = new CancellationToken())
207+
{
208+
var predicate = criteria?.Predicate;
209+
210+
return predicate == null ? GetQuery().CountAsync(cancellationToken) : GetQuery().CountAsync(predicate, cancellationToken);
211+
}
212+
213+
/// <summary>
214+
/// A protected asynchronous overridable method for determining whether the repository contains an entity that satisfies the criteria specified by the <paramref name="criteria" /> from the repository.
215+
/// </summary>
216+
protected override Task<bool> GetExistAsync(ISpecification<TEntity> criteria, CancellationToken cancellationToken = new CancellationToken())
217+
{
218+
if (criteria == null)
219+
throw new ArgumentNullException(nameof(criteria));
220+
221+
var predicate = criteria?.Predicate;
222+
223+
return predicate == null ? GetQuery().AnyAsync(cancellationToken) : GetQuery().AnyAsync(predicate, cancellationToken);
224+
}
225+
226+
#endregion
227+
}
228+
}

0 commit comments

Comments
 (0)