From d8aaa9a831626a73aab982a8a77d654a625834e5 Mon Sep 17 00:00:00 2001 From: honzapatCZ Date: Tue, 25 Aug 2026 13:37:05 +0200 Subject: [PATCH] Reworked some entity creation to work better with proxies --- Models/CommonDbContext.cs | 82 ++++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/Models/CommonDbContext.cs b/Models/CommonDbContext.cs index 3bde51f..10dd323 100644 --- a/Models/CommonDbContext.cs +++ b/Models/CommonDbContext.cs @@ -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().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().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().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(); - 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(); + + 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() + .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(entityT.Name).CreateProxy(constructorArguments);