Gremlin/Gremlin_BlazorServer/Services/GenericController.cs

247 lines
9.0 KiB
C#

using System.Diagnostics;
using Gremlin_BlazorServer.Data.DBClasses;
using Gremlin_BlazorServer.Data.EntityClasses;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata;
namespace Gremlin_BlazorServer.Services;
public class GenericController {
private static readonly GremlinDb gremlinDb = new();
public static IList<TResult>? GetAll<TResult>(string include) where TResult : class, IMetadata {
try {
return gremlinDb.Set<TResult>().Include(include).ToList();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
public static IList<TResult>? GetAll<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
try {
return gremlinDb.Set<TResult>().AsEnumerable().Where(t => search(t)).ToList();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
public static async Task<IList<TResult>?> GetAllAsync<TResult>() where TResult : class, IMetadata {
try {
return await gremlinDb.Set<TResult>().ToListAsync();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
public async Task<IList<TResult>?> GetAllAsync<TResult>(string include) where TResult : class, IMetadata {
try {
return await gremlinDb.Set<TResult>().Include(include).ToListAsync();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
public async Task<IList<TResult>?> GetAllAsync<TResult>(string include1, string include2) where TResult : class, IMetadata {
try {
return await gremlinDb.Set<TResult>().Include(include1).Include(include2).ToListAsync();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
public static async Task<IList<TResult>?> GetAllAsync<TResult>(Predicate<TResult> search) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
try {
return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().Where(t => search(t)).ToList());
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
public async Task<IList<TResult>?> GetAllAsync<TResult>(Predicate<TResult> search, string include) where TResult : class, IMetadata {
ArgumentNullException.ThrowIfNull(search);
try {
return await Task.Run(() => gremlinDb.Set<TResult>().Include(include).AsEnumerable().Where(t => search(t)).ToList());
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return null;
}
}
public static TResult? Get<TResult>(Predicate<TResult> search) where TResult : class, IMetadata, new() {
try {
return gremlinDb.Set<TResult>().AsEnumerable().FirstOrDefault(t => search(t));
}
catch (Exception e) {
Console.WriteLine(e.InnerException);
return null;
}
}
public static async Task<TResult> Get<TResult>(Predicate<TResult> search, string include1) where TResult : class, IMetadata, new() {
ArgumentNullException.ThrowIfNull(search);
try {
return await Task.Run(() => gremlinDb.Set<TResult>().Include(include1).AsEnumerable().First(t => search(t)));
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return new();
}
}
public static async Task<TResult> Get<TResult>(Predicate<TResult> search, string include1, string include2) where TResult : class, IMetadata, new() {
ArgumentNullException.ThrowIfNull(search);
try {
return await Task.Run(() => gremlinDb.Set<TResult>().Include(include1).Include(include2).AsEnumerable().First(t => search(t)));
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return new();
}
}
public static async Task<TResult> GetLastAsync<TResult>() where TResult : class, IMetadata, new() {
try {
return await Task.Run(() => gremlinDb.Set<TResult>().AsEnumerable().Last());
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return new();
}
}
public static int Insert<T>(T entity) where T : class, IMetadata {
try {
gremlinDb.Set<T>().Add(entity);
return gremlinDb.SaveChanges();
}
catch (DbUpdateException ex) {
Console.WriteLine($"{ex.InnerException}");
HandleConcurrencyExceptions(ex);
return -1;
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
public static int Insert<T>(IEnumerable<T> entities) where T : class, IMetadata {
// gremlinDb.Set<T>().ToList(); //Get newest versions fresh from db
try {
gremlinDb.Set<T>().AddRange(entities);
return gremlinDb.SaveChanges();
}
catch (DbUpdateException ex) {
HandleConcurrencyExceptions(ex);
return -1;
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
public static async Task<bool> IsExistingAsync<T>(Predicate<T> search) where T : class, IMetadata {
try {
return await Task.Run(() => gremlinDb.Set<T>().AsEnumerable().Any(t => search(t)));
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return false;
}
}
public static int Update<T>(T entity) where T : class, IMetadata {
try {
gremlinDb.Set<T>().Update(entity);
return gremlinDb.SaveChanges(false);
}
catch (DbUpdateException ex) {
HandleConcurrencyExceptions(ex);
return -1;
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
public static int Update<T>(IEnumerable<T> entities) where T : class, IMetadata {
try {
gremlinDb.Set<T>().UpdateRange(entities);
return gremlinDb.SaveChanges();
}
catch (DbUpdateException ex) {
HandleConcurrencyExceptions(ex);
return -1;
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
public static async Task<int> RemoveAsync<T>(T entity) where T : class, IMetadata {
try {
await Task.Run(() => gremlinDb.Set<T>().Remove(entity));
return await gremlinDb.SaveChangesAsync();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
private static void HandleConcurrencyExceptions(DbUpdateException ex) {
Console.WriteLine($"!!! HandleConcurrencyException: {ex.Message}");
foreach (EntityEntry entry in ex.Entries)
switch (entry.Entity) {
case Quote or CustomDescription or Account or Contact or Product: {
PropertyValues proposedValues = entry.CurrentValues;
PropertyValues? databaseValues = entry.GetDatabaseValues();
foreach (IProperty property in proposedValues.Properties) {
object? proposedValue = proposedValues[property];
object? databaseValue = databaseValues[property];
// TODO: decide which value should be written to database
// proposedValues[property] = <>;
}
// Refresh original values to bypass next concurrency check
entry.OriginalValues.SetValues(proposedValues);
break;
}
default:
throw new NotSupportedException("Don't know how to handle concurrency conflicts for " + entry.Metadata.Name);
}
}
public static async Task<int> RemoveDublicatesAsync<T>() where T : class, IMetadata {
try {
List<T> entities = gremlinDb.Set<T>().AsEnumerable().GroupBy(e => new { e.HashCode}).SelectMany(grp => grp.Skip(1)).ToList();
gremlinDb.Set<T>().RemoveRange(entities);
return await gremlinDb.SaveChangesAsync();
}
catch (Exception exception) {
Console.WriteLine(exception.InnerException);
return 0;
}
}
}