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 { /// /// Abstrakte Basis-Klasse für Repositories /// /// Typ (Klasse) des Repositories public class Repository : IRepository where T : class { private readonly DbContext _context; private readonly DbSet _entities; private AsyncLock _asyncLock; /// /// Erstellt eine Instanz /// /// Instanz eines DBContext /// AsyncLock Helper public Repository(DbContext context, AsyncLock asyncLock) { _asyncLock = asyncLock; _context = context; _entities = _context.Set(); } /// /// Gibt eine Entität anhand der eindeutigen Id zurück /// /// Id der Entität /// Entität oder null, wenn nicht gefunden 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; } } } /// /// Gibt eine Entität anhand der eindeutigen Id zurück /// /// Id der Entität /// Entität oder null, wenn nicht gefunden public virtual async Task 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; } } } /// /// Gibt alle Entitäten zurück /// /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste aller Entitäten public virtual IEnumerable 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; } } } /// /// Gibt alle Entitäten zurück /// /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste aller Entitäten public virtual async Task> 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; } } } /// /// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen /// /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste gefundener Entitäten public virtual IEnumerable Find(Expression> 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; } } } /// /// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen /// /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste gefundener Entitäten public virtual async Task> FindAsync(Expression> 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; } } } /// /// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen mit Sortierung und Skip und Take für Paging /// /// Kriterien /// Sortierung /// Anzahl Datensätze auslassen /// Anzahl Datensätze selektieren /// true wenn Sortierung aufsteigend, false sonst /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste gefundener Entitäten public async Task> FindAsync(Expression> predicate, Expression> 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; } } } /// /// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen. /// Hier wird zuerst die SQL-Abfrage ausgeführt! /// /// SQL-String /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste gefundener Entitäten public IEnumerable Find(string rawSql, Expression> 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; } } } /// /// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen /// Hier wird zuerst die SQL-Abfrage ausgeführt! /// /// SQL-String /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste gefundener Entitäten public async Task> FindAsync(string rawSql, Expression> 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; } } } /// /// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen /// /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste gefundener Entitäten public IQueryable Query(Expression> 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; } } } /// /// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen von einem View /// /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste gefundener Entitäten public IQueryable QueryView(Expression> 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; } } } /// /// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen von einem View /// /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste gefundener Entitäten public async Task> QueryViewListAsync(Expression> 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; } } } /// /// Gibt eine Liste aller Entitäten zurück welche definierten Kriterien entsprechen. /// Hier wird zuerst die SQL-Abfrage ausgeführt! /// /// SQL-String /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Liste gefundener Entitäten public IQueryable Query(string rawSql, Expression> 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; } } } /// /// Gibt eine Entität oder den Default wert zurück /// /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Gefundene entität oder Default-Wert public virtual T SingleOrDefault(Expression> 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; } } } /// /// Gibt eine Entität oder den Default wert zurück /// /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Gefundene entität oder Default-Wert public virtual async Task SingleOrDefaultAsync(Expression> 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; } } } /// /// Gibt eine Entität oder den Default wert zurück /// /// Kriterien /// Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten /// Gefundene entität oder Default-Wert public virtual async Task FirstOrDefaultAsync(Expression> 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; } } } /// /// Fügt eine Entität zum Repository hinzu /// /// Entität public virtual void Add(T entity) { _entities.Add(entity); } /// /// Fügt eine Liste von Entitäten zum Repository hinzu /// /// List von Entitäten public virtual void AddRange(IEnumerable entities) { _entities.AddRange(entities); } /// /// Aktualisieren einer Entität /// /// Entität public void Update(T entity) { _entities.Update(entity); } /// /// Aktualisieren einer Liste von Entitäten /// /// List von Entitäten public void UpdateRange(IEnumerable entities) { _entities.UpdateRange(entities); } /// /// Entfernt eine Entität aus dem Repository /// /// Zu entfernende Entität public virtual void Remove(T entity) { _entities.Remove(entity); } /// /// Entfernt eine Liste von Entitäten aus dem Repository /// /// Liste von Entitäten public virtual void RemoveRange(IEnumerable entities) { _entities.RemoveRange(entities); } /// /// Gibt die Anzahl aller Entitäten zurück /// /// Anzahl Entitäten public int Count() { using (_asyncLock.Lock()) { try { return _entities.Count(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return 0; } } } /// /// Gibt die Anzahl aller Entitäten zurück /// /// Anzahl Entitäten public async Task CountAsync() { using (await _asyncLock.LockAsync()) { try { return await _entities.CountAsync().ConfigureAwait(false); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return 0; } } } /// /// Gibt die Anzahl aller Entitäten zurück die definierten Kriterien entsprechen /// /// Kriterien /// Anzahl Entitäten public int Count(Expression> predicate) { using (_asyncLock.Lock()) { try { return _entities.Count(predicate); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return 0; } } } /// /// Gibt die Anzahl aller Entitäten zurück die definierten Kriterien entsprechen /// /// Kriterien /// Anzahl Entitäten public async Task CountAsync(Expression> predicate) { using (await _asyncLock.LockAsync()) { try { return await _entities.CountAsync(predicate).ConfigureAwait(false); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return 0; } } } /// /// Ausführen eines RAW SQL commands /// /// SQL-String /// Parameter /// Anzahl betroffener Datensätze public async Task 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; } } } } }