615 lines
23 KiB
C#

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using gehGassiApp.Core.Data;
namespace gehGassiApp.Data
{
/// <summary>
/// Abstrakte Basis-Klasse für Repositories
/// </summary>
/// <typeparam name="T">Typ (Klasse) des Repositories</typeparam>
public class Repository<T> : IRepository<T> where T : class
{
private readonly DbContext _context;
private readonly DbSet<T> _entities;
private AsyncLock _asyncLock;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="context">Instanz eines DBContext</param>
/// <param name="asyncLock">AsyncLock Helper</param>
public Repository(DbContext context, AsyncLock asyncLock)
{
_asyncLock = asyncLock;
_context = context;
_entities = _context.Set<T>();
}
/// <summary>
/// Gibt eine Entität anhand der eindeutigen Id zurück
/// </summary>
/// <param name="id">Id der Entität</param>
/// <returns>Entität oder null, wenn nicht gefunden</returns>
public virtual T Get(object id)
{
using (_asyncLock.Lock())
{
try
{
return _entities.Find(id);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Entität anhand der eindeutigen Id zurück
/// </summary>
/// <param name="id">Id der Entität</param>
/// <returns>Entität oder null, wenn nicht gefunden</returns>
public virtual async Task<T> GetAsync(object id)
{
using (await _asyncLock.LockAsync())
{
try
{
return await _entities.FindAsync(id).ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt alle Entitäten zurück
/// </summary>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste aller Entitäten</returns>
public virtual IEnumerable<T> GetAll(bool noTracking = true)
{
using (_asyncLock.Lock())
{
try
{
if (noTracking)
return _entities.AsNoTracking().ToList();
else
return _entities.ToList();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt alle Entitäten zurück
/// </summary>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste aller Entitäten</returns>
public virtual async Task<IEnumerable<T>> GetAllAsync(bool noTracking = true)
{
using (await _asyncLock.LockAsync())
{
try
{
if (noTracking)
return await _entities.AsNoTracking().ToListAsync().ConfigureAwait(false);
else
return await _entities.ToListAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste gefundener Entitäten</returns>
public virtual IEnumerable<T> Find(Expression<Func<T, bool>> predicate, bool noTracking = true)
{
using (_asyncLock.Lock())
{
try
{
if (noTracking)
return _entities.Where(predicate).AsNoTracking().ToList();
else
return _entities.Where(predicate).ToList();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste gefundener Entitäten</returns>
public virtual async Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate, bool noTracking = true)
{
using (await _asyncLock.LockAsync())
{
try
{
if (noTracking)
return await _entities.Where(predicate).AsNoTracking().ToListAsync().ConfigureAwait(false);
else
return await _entities.Where(predicate).ToListAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen mit Sortierung und Skip und Take für Paging
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <param name="orderBySelector">Sortierung</param>
/// <param name="skip">Anzahl Datensätze auslassen</param>
/// <param name="take">Anzahl Datensätze selektieren</param>
/// <param name="ascending">true wenn Sortierung aufsteigend, false sonst</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste gefundener Entitäten</returns>
public async Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderBySelector, int skip, int take, bool ascending, bool noTracking = true)
{
using (await _asyncLock.LockAsync())
{
try
{
if (noTracking)
{
if(ascending)
return await _entities.Where(predicate).OrderBy(orderBySelector).Skip(skip).Take(take).AsNoTracking().ToListAsync().ConfigureAwait(false);
else
return await _entities.Where(predicate).OrderByDescending(orderBySelector).Skip(skip).Take(take).AsNoTracking().ToListAsync().ConfigureAwait(false);
}
else
{
if(ascending)
return await _entities.Where(predicate).OrderBy(orderBySelector).Skip(skip).Take(take).ToListAsync().ConfigureAwait(false);
else
return await _entities.Where(predicate).OrderByDescending(orderBySelector).Skip(skip).Take(take).ToListAsync().ConfigureAwait(false);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen.
/// Hier wird zuerst die SQL-Abfrage ausgeführt!
/// </summary>
/// <param name="rawSql">SQL-String</param>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste gefundener Entitäten</returns>
public IEnumerable<T> Find(string rawSql, Expression<Func<T, bool>> predicate = null, bool noTracking = true)
{
using (_asyncLock.Lock())
{
try
{
var result = _entities.FromSqlRaw(rawSql);
if (predicate != null)
result = result.Where(predicate);
if (noTracking)
return result.AsNoTracking().ToList();
else
return result.ToList();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen
/// Hier wird zuerst die SQL-Abfrage ausgeführt!
/// </summary>
/// <param name="rawSql">SQL-String</param>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste gefundener Entitäten</returns>
public async Task<IEnumerable<T>> FindAsync(string rawSql, Expression<Func<T, bool>> predicate = null, bool noTracking = true)
{
using (await _asyncLock.LockAsync())
{
try
{
var result = _entities.FromSqlRaw(rawSql);
if (predicate != null)
result = result.Where(predicate);
if (noTracking)
return await result.AsNoTracking().ToListAsync().ConfigureAwait(false);
else
return await result.ToListAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste gefundener Entitäten</returns>
public IQueryable<T> Query(Expression<Func<T, bool>> predicate, bool noTracking = true)
{
using (_asyncLock.Lock())
{
try
{
if (noTracking)
return _entities.AsNoTracking().Where(predicate);
else
return _entities.Where(predicate);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen von einem View
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste gefundener Entitäten</returns>
public IQueryable<T> QueryView(Expression<Func<T, bool>> predicate, bool noTracking = true)
{
using (_asyncLock.Lock())
{
try
{
if (noTracking)
return _entities.AsNoTracking().Where(predicate);
else
return _entities.Where(predicate);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen von einem View
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste gefundener Entitäten</returns>
public async Task<IEnumerable<T>> QueryViewListAsync(Expression<Func<T, bool>> predicate, bool noTracking = true)
{
using (await _asyncLock.LockAsync())
{
try
{
if (noTracking)
return await _entities.AsNoTracking().Where(predicate).ToListAsync().ConfigureAwait(false);
else
return await _entities.Where(predicate).ToListAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen.
/// Hier wird zuerst die SQL-Abfrage ausgeführt!
/// </summary>
/// <param name="rawSql">SQL-String</param>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Liste gefundener Entitäten</returns>
public IQueryable<T> Query(string rawSql, Expression<Func<T, bool>> predicate = null, bool noTracking = true)
{
using (_asyncLock.Lock())
{
try
{
var result = _entities.FromSqlRaw(rawSql);
if (predicate != null)
result = result.Where(predicate);
if (noTracking)
return result.AsNoTracking();
else
return result;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Entität oder den Default wert zurück
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Gefundene entität oder Default-Wert</returns>
public virtual T SingleOrDefault(Expression<Func<T, bool>> predicate, bool noTracking = true)
{
using (_asyncLock.Lock())
{
try
{
if (noTracking)
return _entities.AsNoTracking().SingleOrDefault(predicate);
else
return _entities.SingleOrDefault(predicate);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Entität oder den Default wert zurück
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Gefundene entität oder Default-Wert</returns>
public virtual async Task<T> SingleOrDefaultAsync(Expression<Func<T, bool>> predicate, bool noTracking = true)
{
using (await _asyncLock.LockAsync())
{
try
{
if (noTracking)
return await _entities.AsNoTracking().SingleOrDefaultAsync(predicate).ConfigureAwait(false);
else
return await _entities.SingleOrDefaultAsync(predicate).ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Gibt eine Entität oder den Default wert zurück
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
/// <returns>Gefundene entität oder Default-Wert</returns>
public virtual async Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, bool noTracking = true)
{
using (await _asyncLock.LockAsync())
{
try
{
if (noTracking)
return await _entities.AsNoTracking().FirstOrDefaultAsync(predicate).ConfigureAwait(false);
else
return await _entities.FirstOrDefaultAsync(predicate).ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return default;
}
}
}
/// <summary>
/// Fügt eine Entität zum Repository hinzu
/// </summary>
/// <param name="entity">Entität</param>
public virtual void Add(T entity)
{
_entities.Add(entity);
}
/// <summary>
/// Fügt eine Liste von Entitäten zum Repository hinzu
/// </summary>
/// <param name="entities">List von Entitäten</param>
public virtual void AddRange(IEnumerable<T> entities)
{
_entities.AddRange(entities);
}
/// <summary>
/// Aktualisieren einer Entität
/// </summary>
/// <param name="entity">Entität</param>
public void Update(T entity)
{
_entities.Update(entity);
}
/// <summary>
/// Aktualisieren einer Liste von Entitäten
/// </summary>
/// <param name="entities">List von Entitäten</param>
public void UpdateRange(IEnumerable<T> entities)
{
_entities.UpdateRange(entities);
}
/// <summary>
/// Entfernt eine Entität aus dem Repository
/// </summary>
/// <param name="entity">Zu entfernende Entität</param>
public virtual void Remove(T entity)
{
_entities.Remove(entity);
}
/// <summary>
/// Entfernt eine Liste von Entitäten aus dem Repository
/// </summary>
/// <param name="entities">Liste von Entitäten</param>
public virtual void RemoveRange(IEnumerable<T> entities)
{
_entities.RemoveRange(entities);
}
/// <summary>
/// Gibt die Anzahl aller Entitäten zurück
/// </summary>
/// <returns>Anzahl Entitäten</returns>
public int Count()
{
using (_asyncLock.Lock())
{
try
{
return _entities.Count();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return 0;
}
}
}
/// <summary>
/// Gibt die Anzahl aller Entitäten zurück
/// </summary>
/// <returns>Anzahl Entitäten</returns>
public async Task<int> CountAsync()
{
using (await _asyncLock.LockAsync())
{
try
{
return await _entities.CountAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return 0;
}
}
}
/// <summary>
/// Gibt die Anzahl aller Entitäten zurück die definierten Kriterien entsprechen
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <returns>Anzahl Entitäten</returns>
public int Count(Expression<Func<T, bool>> predicate)
{
using (_asyncLock.Lock())
{
try
{
return _entities.Count(predicate);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return 0;
}
}
}
/// <summary>
/// Gibt die Anzahl aller Entitäten zurück die definierten Kriterien entsprechen
/// </summary>
/// <param name="predicate">Kriterien</param>
/// <returns>Anzahl Entitäten</returns>
public async Task<int> CountAsync(Expression<Func<T, bool>> predicate)
{
using (await _asyncLock.LockAsync())
{
try
{
return await _entities.CountAsync(predicate).ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return 0;
}
}
}
/// <summary>
/// Ausführen eines RAW SQL commands
/// </summary>
/// <param name="sql">SQL-String</param>
/// <param name="parameters">Parameter</param>
/// <returns>Anzahl betroffener Datensätze</returns>
public async Task<int> ExecuteRawSqlAsync(string sql, object[] parameters)
{
using (await _asyncLock.LockAsync())
{
try
{
return await _context.Database.ExecuteSqlRawAsync(sql, parameters).ConfigureAwait(false);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return 0;
}
}
}
}
}