Open AllanMichaelsen opened 4 months ago
@AllanMichaelsen I am not able to reproduce this--see my code below. Please attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate.
using (var context = new SomeDbContext())
{
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
context.Add(new SubscriptionPlan());
await context.SaveChangesAsync();
}
using (var context = new SomeDbContext())
{
var results = await context.SubscriptionPlans.ToListAsync();
}
public class SomeDbContext : DbContext
{
public DbSet<SubscriptionPlan> SubscriptionPlans => Set<SubscriptionPlan>();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer(@"Data Source=localhost;Database=One;Integrated Security=True;Trust Server Certificate=True")
.LogTo(Console.WriteLine, LogLevel.Information)
.AddInterceptors(MaterializationInterceptor.Instance)
.EnableSensitiveDataLogging();
}
public class SubscriptionPlan
{
public int Id { get; set; }
public bool IsFree { get; set; }
public string? Bar { get; set; }
}
public class MaterializationInterceptor : IMaterializationInterceptor
{
private MaterializationInterceptor() { }
public object CreatedInstance(MaterializationInterceptionData materializationData, object entity)
{
throw new Exception("CreatedInstance");
}
public InterceptionResult<object> CreatingInstance(MaterializationInterceptionData materializationData, InterceptionResult<object> result)
{
throw new Exception("CreatingInstance");
}
public object InitializedInstance(MaterializationInterceptionData materializationData, object instance)
{
throw new Exception("InitializedInstance");
}
public InterceptionResult InitializingInstance(MaterializationInterceptionData materializationData, object entity, InterceptionResult result)
{
throw new Exception("InitializingInstance");
}
public static MaterializationInterceptor Instance { get; } = new();
}
When creating the demo project, the interceptor was hit. I tried again to dig into the difference between my project and the demo project and I did find the culprit.
I use AutoMapperin my project and to be more specific I use the method: .ProjectTo<TOut>(mapper.ConfigurationProvider)
as seen below.
if (typeof(TOut) == typeof(T))
{
return await queryable
.Cast<TOut>()
.FirstOrDefaultAsync();
}
return await queryable
.ProjectTo<TOut>(mapper.ConfigurationProvider)
.FirstOrDefaultAsync();
So when I request TOut to be of my entity type the Interceptor is hit, but when I request my mapped Dto object, it is not. It seems that AutoMapper does not utilize the "InitializedInstance" (or any) method in the IMaterializationInterceptor.
The question is now. Is there a solution to this or do I have to rethink my mapping setup (I hope not)
@AllanMichaelsen The materialization interceptor only kicks in for the materialization of entity type instances, not arbitrary projected types.
Note for team triage: it could be useful to have an interceptor for creation of non-entity types.
Noted. I have made a temporary fix via my Automapper projection and await an update for an non-entity inceptor.
Wil such update be posted here in this thread? Both if it is put in and in case it is decided not implement the feature?
@AllanMichaelsen If we decide it is worthwhile, then the issue will go on the backlog and be prioritized accordingly. Realistically, it's unlikely to happen any time soon.
I added an IMaterializationInterceptor like below (the exceptions are for this purpose only):
Added to my contect as:
When I run a query against my context I didn't get the expected result from the value substitution I have in the "InitializedInstance" method. During debugging I can see that the constructor is hit, but my breakpoints are never hit. So for some reason the methods (any of the four) are never hit.
I also have a "DbCommandInterceptor" and a "SaveChangesInterceptor". Both of those work fine.
EF Core version: 8,0,2 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 8.0 Operating system: Windows 11 Pro IDE: Visual Studio 2022 17.9.0 Preview 4