Created
June 13, 2018 11:46
-
-
Save christianhelle/4098f7e04246637d25117115eba6ce39 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Data.Entity; | |
using System.Data.Entity.Migrations; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace ChristianHelle.Toolbox.Data.Repositories | |
{ | |
public interface IDatabaseContextFactory | |
{ | |
DbContext Create(string nameOrConnectionString); | |
} | |
public interface IRepository<T> | |
{ | |
IDatabaseContextFactory ContextFactory { get; } | |
string NameOrConnectionString { get; set; } | |
Task<IEnumerable<T>> GetAllAsync(bool orderByDesc = false, params string[] includeProperties); | |
Task<IEnumerable<T>> GetAsync(int page = 0, int count = int.MaxValue, bool orderByDesc = false, params string[] includeProperties); | |
Task<T> FindAsync(int id, params string[] includeProperties); | |
Task<bool> ExistsAsync(T entity); | |
Task<T> CreateAsync(); | |
Task<T> CreateAsync(T entity); | |
T Create(T entity); | |
Task<IEnumerable<T>> CreateAsync(IEnumerable<T> entity); | |
Task<T> RefreshAsync(T entity); | |
Task<T> UpdateAsync(T entity); | |
Task<IEnumerable<T>> UpdateAsync(IEnumerable<T> entities); | |
Task DeleteAsync(int id); | |
Task DeleteAsync(T entity); | |
Task DeleteAsync(IEnumerable<T> entities); | |
} | |
public interface IIdentifiableType | |
{ | |
int Id { get;set; } | |
} | |
public interface IModifiableItem | |
{ | |
DateTime? LastModifiedDate { get; set; } | |
} | |
public class Repository<T> : IRepository<T> where T : class, IIdentifiableType | |
{ | |
public Repository(IDatabaseContextFactory contextFactory, string nameOrConnectionString = null) | |
{ | |
ContextFactory = contextFactory; | |
NameOrConnectionString = nameOrConnectionString; | |
} | |
public IDatabaseContextFactory ContextFactory { get; } | |
public string NameOrConnectionString { get; set; } | |
public virtual async Task<IEnumerable<T>> GetAllAsync(bool orderByDesc = false, params string[] includeProperties) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
IQueryable<T> set = context.Set<T>(); | |
set = orderByDesc ? set.OrderByDescending(c => c.Id) : set.OrderBy(c => c.Id); | |
set = includeProperties.Aggregate(set, (current, property) => current.Include(property)); | |
return await set.ToListAsync(); | |
} | |
} | |
public virtual async Task<IEnumerable<T>> GetAsync(int page = 0, int count = 2147483647, bool orderByDesc = false, params string[] includeProperties) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
IQueryable<T> set = context.Set<T>(); | |
set = orderByDesc ? set.OrderByDescending(c => c.Id) : set.OrderBy(c => c.Id); | |
set = includeProperties.Aggregate(set, (current, property) => current.Include(property)); | |
return await set.Skip(page*count) | |
.Take(count) | |
.ToListAsync(); | |
} | |
} | |
public virtual async Task<T> FindAsync(int id, params string[] includeProperties) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
IQueryable<T> set = context.Set<T>(); | |
set = includeProperties.Aggregate(set, (current, property) => current?.Include(property)); | |
return await (set?.FirstOrDefaultAsync(c => c.Id == id) ?? Task.FromResult<T>(null)); | |
} | |
} | |
public virtual async Task<bool> ExistsAsync(T entity) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
return await (context.Set<T>()?.FindAsync(entity?.Id) ?? Task.FromResult<T>(null)) != null; | |
} | |
public virtual Task<T> CreateAsync() => CreateAsync(Activator.CreateInstance<T>()); | |
public virtual async Task<T> CreateAsync(T entity) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
context.Set<T>()?.Add(entity); | |
await context.SaveChangesAsync(); | |
} | |
return entity; | |
} | |
public T Create(T entity) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
context.Set<T>()?.Add(entity); | |
context.SaveChanges(); | |
} | |
return entity; | |
} | |
public virtual async Task<IEnumerable<T>> CreateAsync(IEnumerable<T> entities) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
context.Set<T>()?.AddRange(entities); | |
await context.SaveChangesAsync(); | |
} | |
return entities; | |
} | |
public virtual async Task<T> RefreshAsync(T entity) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
return await (context.Set<T>()?.FindAsync(entity?.Id) ?? Task.FromResult<T>(null)); | |
} | |
public virtual async Task<T> UpdateAsync(T entity) | |
{ | |
if (entity == null) | |
throw new ArgumentNullException(nameof(entity)); | |
if (entity.Id == 0) | |
throw new ArgumentException("Id must not be 0 otherwise this method will create a insert a new record"); | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
TryUpdateLastModifiedDate(entity); | |
context.Set<T>()?.AddOrUpdate(t => t.Id, entity); | |
await context.SaveChangesAsync(); | |
} | |
return entity; | |
} | |
public virtual async Task<IEnumerable<T>> UpdateAsync(IEnumerable<T> entities) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
foreach (var entity in entities) | |
{ | |
TryUpdateLastModifiedDate(entity); | |
context.Set<T>()?.Attach(entity); | |
} | |
await context.SaveChangesAsync(); | |
} | |
return entities; | |
} | |
private static void TryUpdateLastModifiedDate(T entity) | |
{ | |
var modifiableItem = entity as IModifiableItem; | |
if (modifiableItem != null) | |
modifiableItem.LastModifiedDate = DateTime.UtcNow; | |
} | |
public virtual async Task DeleteAsync(int id) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
var entity = await (context.Set<T>()?.FindAsync(id) ?? Task.FromResult<T>(null)); | |
context.Set<T>()?.Remove(entity); | |
await context.SaveChangesAsync(); | |
} | |
} | |
public virtual async Task DeleteAsync(T entity) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
context.Set<T>()?.Attach(entity); | |
context.Set<T>()?.Remove(entity); | |
await context.SaveChangesAsync(); | |
} | |
} | |
public virtual async Task DeleteAsync(IEnumerable<T> entities) | |
{ | |
using (var context = ContextFactory.Create(NameOrConnectionString)) | |
{ | |
var list = entities.ToList(); | |
foreach (var entity in list) | |
context.Set<T>()?.Attach(entity); | |
context.Set<T>()?.RemoveRange(list); | |
await context.SaveChangesAsync(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment