190 lines
5.5 KiB
C#
190 lines
5.5 KiB
C#
|
|
|
|
using System.Globalization;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using AutoMapPropertyHelper;
|
|
using EntityFrameworkCore.Projectables;
|
|
using Microsoft.AspNetCore.Http.HttpResults;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace NejCommon.Models;
|
|
|
|
|
|
public abstract class CommonDbContext : DbContext
|
|
{
|
|
public CommonDbContext() : base()
|
|
{
|
|
}
|
|
public CommonDbContext(DbContextOptions options)
|
|
: base(options)
|
|
{
|
|
}
|
|
|
|
public abstract CommonDbContext CreateCopy();
|
|
|
|
public async Task<bool> ApiSaveChangesAsync()
|
|
{
|
|
try
|
|
{
|
|
await SaveChangesAsync();
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine("Error saving db: " + ex.Message);
|
|
Console.WriteLine(ex.StackTrace);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static BadRequest<Error> SaveError = TypedResults.BadRequest(new Error
|
|
{
|
|
Message = "Error saving data to database"
|
|
});
|
|
|
|
public async Task<Results<BadRequest<Error>, T1>> ApiSaveChangesAsync<T1>(T1 value) where T1 : IResult
|
|
{
|
|
var res = await ApiSaveChangesAsync();
|
|
|
|
if (res)
|
|
return value;
|
|
else
|
|
return SaveError;
|
|
}
|
|
public async Task<Results<BadRequest<Error>, CreatedAtRoute<T2>>> ApiSaveChangesAsyncCreate<T1, T2>(IServiceProvider providers, T1 value, bool apply = true, T2? response = null) where T2 : class, IAutomappedAttribute<T1, T2>, new()
|
|
{
|
|
if(response == null)
|
|
response = new T2();
|
|
if (!apply)
|
|
return TypedResults.CreatedAtRoute(response.ApplyFrom(providers, value));
|
|
|
|
var res = await ApiSaveChangesAsync();
|
|
|
|
if (res)
|
|
return TypedResults.CreatedAtRoute(response.ApplyFrom(providers, value));
|
|
else
|
|
return SaveError;
|
|
}
|
|
public async Task<Results<BadRequest<Error>, Ok<T2>>> ApiSaveChangesAsyncOk<T1, T2>(IServiceProvider providers, T1 value, bool apply = true, T2? response = null) where T2 : class, IAutomappedAttribute<T1, T2>, new()
|
|
{
|
|
if(response == null)
|
|
response = new T2();
|
|
if (!apply)
|
|
return TypedResults.Ok(response.ApplyFrom(providers, value));
|
|
|
|
var res = await ApiSaveChangesAsync();
|
|
|
|
if (res)
|
|
return TypedResults.Ok(response.ApplyFrom(providers, value));
|
|
else
|
|
return SaveError;
|
|
}
|
|
public async Task<Results<BadRequest<Error>, Ok>> ApiSaveChangesAsyncOk()
|
|
{
|
|
var res = await ApiSaveChangesAsync();
|
|
|
|
if (res)
|
|
return TypedResults.Ok();
|
|
else
|
|
return SaveError;
|
|
}
|
|
public async Task<T> FindOrCreateAsync<T>(Expression<Func<T, bool>> predicate, Func<T> factory) where T : class
|
|
{
|
|
var entity = ChangeTracker.Entries<T>().Select(x => x.Entity).FirstOrDefault(predicate.Compile());
|
|
|
|
//find in change tracker
|
|
if (entity != null && Entry(entity).State == EntityState.Deleted)
|
|
{
|
|
Entry(entity).State = EntityState.Modified;
|
|
}
|
|
|
|
//find in currentDb
|
|
if (entity == null)
|
|
{
|
|
entity = await Set<T>().FirstOrDefaultAsync(predicate);
|
|
}
|
|
|
|
//find in up-to-date db
|
|
if (entity == null)
|
|
{
|
|
var newAppDB = CreateCopy();
|
|
|
|
entity = await newAppDB.Set<T>().FirstOrDefaultAsync(predicate);
|
|
|
|
//track the entity if it's not null and not already being tracked
|
|
if (entity != null && this.Entry(entity).State == EntityState.Detached)
|
|
Attach(entity);
|
|
}
|
|
|
|
//create if not found
|
|
if (entity == null)
|
|
{
|
|
var newEntity = factory();
|
|
await this.AddAsync(newEntity);
|
|
entity = newEntity;
|
|
}
|
|
|
|
return entity;
|
|
}
|
|
public T FindOrCreate<T>(Expression<Func<T, bool>> predicate, Func<T> factory) where T : class
|
|
{
|
|
var entity = ChangeTracker.Entries<T>().Where(e => e.State != EntityState.Deleted).Select(x => x.Entity).FirstOrDefault(predicate.Compile());
|
|
|
|
//find in change tracker
|
|
if (entity != null && Entry(entity).State == EntityState.Deleted)
|
|
{
|
|
Entry(entity).State = EntityState.Modified;
|
|
}
|
|
|
|
//find in currentDb
|
|
if (entity == null)
|
|
{
|
|
entity = Set<T>().FirstOrDefault(predicate);
|
|
}
|
|
|
|
//find in up-to-date db
|
|
if (entity == null)
|
|
{
|
|
var newAppDB = CreateCopy();
|
|
|
|
entity = newAppDB.Set<T>().FirstOrDefault(predicate);
|
|
if (entity != null)
|
|
Attach(entity);
|
|
}
|
|
|
|
//create if not found
|
|
if (entity == null)
|
|
{
|
|
var newEntity = factory();
|
|
this.Add(newEntity);
|
|
entity = newEntity;
|
|
}
|
|
|
|
return entity;
|
|
}
|
|
|
|
public T Create<T>(Action<T> config = null, params object[] constructorArguments)
|
|
{
|
|
var entity = this.CreateProxy<T>(constructorArguments);
|
|
|
|
config?.Invoke(entity);
|
|
this.Add(entity);
|
|
this.ChangeTracker.DetectChanges();
|
|
return entity;
|
|
}
|
|
public object Create(Type entityType, Action<object> config = null, params object[] constructorArguments)
|
|
{
|
|
var entity = this.CreateProxy(entityType, constructorArguments);
|
|
|
|
config?.Invoke(entity);
|
|
this.Add(entity);
|
|
this.ChangeTracker.DetectChanges();
|
|
return entity;
|
|
}
|
|
|
|
public void ApplyRelationships()
|
|
{
|
|
this.ChangeTracker.DetectChanges();
|
|
}
|
|
} |