Reworked some entity creation to work better with proxies

This commit is contained in:
honzapatCZ 2026-08-25 13:37:05 +02:00
parent 817c0d9d32
commit d8aaa9a831

View File

@ -7,6 +7,11 @@ using AutoMapPropertyHelper;
using EntityFrameworkCore.Projectables;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Proxies.Internal;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Storage;
namespace NejCommon.Models;
@ -57,12 +62,12 @@ public abstract class CommonDbContext : DbContext
if (response == null)
response = new T2();
if (!apply)
return TypedResults.CreatedAtRoute(response.ApplyFrom(providers, value));
return TypedResults.CreatedAtRoute((T2)response.ApplyFrom(providers, (object)value));
var res = await ApiSaveChangesAsync();
if (res)
return TypedResults.CreatedAtRoute(response.ApplyFrom(providers, value));
return TypedResults.CreatedAtRoute((T2)response.ApplyFrom(providers, (object)value));
else
return SaveError;
}
@ -71,12 +76,12 @@ public abstract class CommonDbContext : DbContext
if (response == null)
response = new T2();
if (!apply)
return TypedResults.Ok(response.ApplyFrom(providers, value));
return TypedResults.Ok((T2)response.ApplyFrom(providers, (object)value));
var res = await ApiSaveChangesAsync();
if (res)
return TypedResults.Ok(response.ApplyFrom(providers, value));
return TypedResults.Ok((T2)response.ApplyFrom(providers, (object)value));
else
return SaveError;
}
@ -107,18 +112,23 @@ public abstract class CommonDbContext : DbContext
{
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 change tracker
if (entity != null && Entry(entity).State == EntityState.Deleted)
{
/*
Entry(entity).State = EntityState.Modified;
Attach(entity);*/
Entry(entity).State = EntityState.Detached;
entity = await Set<T>().FirstOrDefaultAsync(predicate);
}
//find in up-to-date db
if (entity == null)
{
@ -184,15 +194,59 @@ public abstract class CommonDbContext : DbContext
.GetEntityTypes()
.Where(x => x.ClrType == typeof(TParent))
.FirstOrDefault();
var entityT = candidates?.FindNavigation(navigationName)?.TargetEntityType;
var nav = candidates?.FindNavigation(navigationName);
var entityT = nav?.TargetEntityType;
if (entityT == null || entityT.IsOwned())
{
var childEntity = new T();
/*
var source = this.GetService<IStructuralTypeMaterializerSource>();
config?.Invoke(childEntity);
var materializer =
source.GetEmptyMaterializer(entityT);
return childEntity;
var materializationContext =
new MaterializationContext(
ValueBuffer.Empty,
this);
var val = (T)materializer(materializationContext);
*/
var factory = this.GetService<IProxyFactory>();
var val = (T)factory.CreateProxy(
this,
entityT,
constructorArguments);
if (!nav.IsCollection)
{
var refVal = Entry(parentI).Reference(navigationName);
refVal.CurrentValue = val;
if (refVal.TargetEntry == null)
throw new Exception();
refVal.TargetEntry.State = EntityState.Added;
}
//this.ChangeTracker.DetectChanges();
/*
var refVal = this.Set<TParent>()
.Entry(parentI)
.Reference(navigationName);
refVal.CurrentValue = val;
Attach(val);
if (refVal.TargetEntry == null)
throw new Exception("test");
*/
config?.Invoke(val);
return val;
}
var entity = this.Set<T>(entityT.Name).CreateProxy(constructorArguments);