Injizierter scoped Service in EF Core DBSet in Hotchocolat 15: Der Scoped -Service kann nicht vom Root -Anbieter gelöst C#

Ein Treffpunkt für C#-Programmierer
Guest
 Injizierter scoped Service in EF Core DBSet in Hotchocolat 15: Der Scoped -Service kann nicht vom Root -Anbieter gelöst

Post by Guest »

Ich habe kürzlich mein Backend GraphQL -Backend mit EF Core und Hotchocolat von Version 12.x.x bis 15.0.3 aktualisiert. Build/Start funktioniert gut. Ich habe jedoch Probleme beim Abfragen, da der Fehler unerwarteter Ausführungsfehler geworfen wird. Ich verwende einen httpaccessor und extrahiere JWT -Informationen daraus und speichere sie in den Service iRequestIdentity . Dies wurde seitdem in den DBContext injiziert, wo ich zwei Dinge damit mache:

Globale Abfragefilter auf die Entitäten anwenden
Implementieren Sie eine "geändert nach" Logik, wobei die Benutzer -ID nach jedem Schreiben auf einen Datensatz aktualisiert wird. < /li>
< /ol>
Es gab dort Eine Änderung in HC15 In der Art und Weise, wie DI Scope und EF -Registrierung jetzt durchgeführt werden. Ich vermute, dass dies die Hauptursache ist. Ich kann den Fehler beheben, aber dafür muss ich 1) und 2) oben entfernen, was ich wirklich vermeiden möchte. < /P>
Hier ist meine Argumentation und was ich bis jetzt getan habe - Dies sind die relevanten Dienste und die DI-Registrierung: < /p>

Code: Select all

public interface IRequestIdentity
{
Guid TenantId { get; init; }
Guid UserId { get; init; }
}

public record RequestIdentity(Guid TenantId, Guid UserId) : IRequestIdentity;

builder.Services.AddScoped(sp =>
{
HttpContext? httpContext = sp.GetRequiredService().HttpContext;
ArgumentNullException.ThrowIfNull(httpContext);
ClaimsPrincipal user = httpContext.User;
return new RequestIdentity(user.TenantId, user.Id);
});

builder.Services.AddDbContext(opt =>
{
string dbPath = builder.Configuration.GetRequiredValue("dbPath");
opt.UseSqlite($"Data Source={dbPath}");
});
< /code>
Und dies ist mein EF -Kerndatenmodell. Beachten Sie das Verhalten für 1) in den OnModelCreating 
und für 2) in den Savechanges -Methoden. Beachten Sie auch, dass ich IrequestIdentität in den ctor des dbSet inject inject inject inject
injiziere.

Code: Select all

public record Animal
{
public Guid TenantId { get; set; }
public Guid ChangedBy { get; set; }
[MaxLength(50)] public string Name { get; set; }
}

public class DataContext : DbContext
{
public DbSet Animals { get; init; } = null!;
public readonly IRequestIdentity RequestIdentity;

public DataContext(DbContextOptions options, IRequestIdentity reqId) : base(options)
{
RequestIdentity = reqId;
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(e =>
{
e.ToTable("Animals");
e.HasQueryFilter(a => a.TenantId == RequestIdentity.TenantId);
});
}

public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
// updated ChangedBy property

return base.SaveChanges(acceptAllChangesOnSuccess);
}
}
< /code>
Hier ist die heiße Schokoladenschicht auf dem EF -Kern.  Das Modell und das Schema werden im GraphQL Nitro Explorer gut angezeigt.public partial class Query
{
public IQueryable GetAnimals(DataContext ctx)
=> ctx.Animals;
}
< /code>
query {
animals {
id
}
}
< /code>
Ausführen dieser Abfrage führt jetzt zu einem Fehler < /p>

{"Fehler": [
{"Nachricht ":" Unerwarteter Ausführungsfehler ",

" Positionen ": [{" Zeile ": 2," Spalte ": 3}],

" Pfad ": [" Tiere "] }], "data": null}

Nach der offiziellen HC -Dokumentation hat sich die Art und Weise, wie EF Core verdrahtet ist /> 
builder.Services.AddDbContextFactory(opt =>
{
string dbPath = builder.Configuration.GetRequiredValue("dbPath");
opt.UseSqlite($"Data Source={dbPath}");
});

//...

builder.Services.AddGraphQLServer().RegisterDbContextFactory();
< /code>
Die gleiche Abfrage führt dann zu diesem Fehler < /p>

{"Fehler":

[{"Nachricht": "Unerwarteter Ausführungsfehler",

"Positionen": [{"Zeile": 2, "Spalte": 3}], "Pfad": ["Animals"], "Erweiterungen": {"Nachricht": "Kann nicht den skopierten Service 'irequestidentity' vom Root -Anbieter beheben.", "Stacktrace": "..."}}], "Daten": null} 
< /blockquote>
afaik, der dbContextFactory < /code> ist ein Singleton, in dem ich versuche, abzuleiten Scoped-Service, der nicht funktioniert. Dort habe ich auch mit dem Werksansatz versucht, der in der Dokumentation festgelegt ist: < /p>
public partial class Query
{
public IQueryable GetAnimalsWithFactory(IDbContextFactory ctxFactory)
=> ctxFactory.CreateDbContext().Animals;
}
Dies funktioniert jedoch auch nicht. Die Anfragen kehren beide erfolgreich zurück. Aber ich verliere meine Anforderungen 1) und 2) oben. Während ich 1 ausgleichen könnte, indem ich nur zusätzliche .where () Filter in der Abfrage hinzufügt, habe ich keine Ahnung, wie ich 2), ohne etwas in den DBSet .
Haben Sie eine Idee, wie ich diese Funktionsweise machen könnte? Ihre Gedanken dazu und jedes Feedback werden sehr geschätzt!

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post