Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Warum werden Entitäten und deren Beziehungen in ASP.NET Core Views nicht angezeigt?
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

Warum werden Entitäten und deren Beziehungen in ASP.NET Core Views nicht angezeigt?

beantworten | zitieren | melden

Hi, folgender Code:


    public class Order
    {
        public int Id { get; set; }
        public string Title { get; set; }

        public Customer Customer { get; set; }
    }

    public class Customer
    {
        public int Id { get; set; }
        public string Name_Last { get; set; }
        public string Name_First { get; set; }
        public List<Order> Orders { get; set; }

        [Display(Name = "Full Name")]
        public string FullName
        {
            get
            {
                return Name_Last + ", " + Name_First;
            }
        }
    }

Die Objekte haben ich in einem DbContext. Am Start lege ich mir mit einer Seed-Klasse ein paar Beispiel Daten an und verknüpfe dort die Objekte bereits mit order1.Customer = customer1 usw.
Das geht soweit und mir wird in der Datenübersicht der Tabelle das auch angezeigt (also der Fremdkey).

Wenn ich jetzt aber in den Views (Order-Details) den Customer anzeigen lassen will, erscheint gar nichts.


        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Customer.FullName)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Customer.FullName)
        </dd>

Der DisplayName wird angezeigt aber kein Inhalt.
Kann mir jemand helfen? Danke!
private Nachricht | Beiträge des Benutzers
Papst
myCSharp.de - Experte



Dabei seit:
Beiträge: 362
Herkunft: Kassel

beantworten | zitieren | melden

Vermutlich hat er einfach die Child Items nicht geladen, dies könntest du in deinem Query mittels

Include(c => c.Orders)

lösen.

Allerdings solltest du eine saubere Schichtentrennung verwenden, dann würde das Problem nicht auftreten:
[Artikel] Drei-Schichten-Architektur
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Der empfohlene Weg sind Projektionen: die Business-Schicht ist dabei in der Verantwortung.
Tools wie AutoMapper unterstützen dabei die Query-Erzeugung mit Hilfe von Expressions.
AutoMapper - ProjectTo

Wie aber Papst schon sagte musst Du ordentlich die Schichten trennen.
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Danke für die Antworten!
Zitat von Abt
Der empfohlene Weg sind Projektionen: die Business-Schicht ist dabei in der Verantwortung.
Tools wie AutoMapper unterstützen dabei die Query-Erzeugung mit Hilfe von Expressions.
AutoMapper - ProjectTo

Wie aber Papst schon sagte musst Du ordentlich die Schichten trennen.

Du meinst jetzt dass ich im Controller, beim Aufruf von Order Details z.B. ein ViewBag übergebe mit dem Customer der Order oder?



public List<Order> Orders { get; set; }


Also das dann weglassen und nur Customer.Where(p=>p.Id==CustomerId).First() im Controller übergeben?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von JimStark am .
private Nachricht | Beiträge des Benutzers
Papst
myCSharp.de - Experte



Dabei seit:
Beiträge: 362
Herkunft: Kassel

beantworten | zitieren | melden

In dem von mir verlinkten Artikel ist es gut beschrieben. Wenn du eine Schichtentrennung zwischen Datenhaltung und Datenpräsentation einführst und eigene Klassen in den Schichten hast, musst du zwischen diesen Klassen eine Projektion erzeugen.

Für die Projektion kannst du AutoMapper verwenden - musst es aber nicht.

Das Grundproblem (aber nicht die Lösung) ist, dass Entity Framework per default bei 1:n Verknüpfungen automatisch alle Datensätze mitlädt. Vermutlich ist, wenn dein Model gerendert wird, bereits die Datenbank Verbindung wieder geschlossen und damit können die Datensätze nicht automatisiert nachgeladen werden.
AutoMapper würde bei einer ausgeführten Projektion die Datensätze aber zugreifen wollen und diese damit nachladen (gesetzt dem Fall, du hast EFCore so konfiguriert, dass es das tut - ich bin aber nicht sicher, ob es das in der aktuellen Version überhaupt kann, ich habe das zum letzten mal in EF 6 benutzt).


Edit: verlinkt ist nicht gepostet - im Text korrigiert
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Papst am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Zitat von JimStark
Du meinst jetzt dass ich im Controller, beim Aufruf von Order Details z.B. ein ViewBag übergebe mit dem Customer der Order oder?

Nein, das ist völlig falsch.

Deine Business Logik gehört gar nicht in die ASP.NET Anwendung sondern in eine Bibliothek.
Die Logik rufst Du dann im Controller auf.

Beispiel: wir haben hier eine Profilansicht im Forum, dann würde die Action so aussehen:

        [Route("{userId:int}/{userName}", Name = PortalRouter.Routes.UserProfileView)]
        public async Task<IActionResult> Profile(int userId, string userName)
        {
            // business logik aufrufen um die projektion des users zu laden
            var p = await _eventDispatcher.Send(new GetUserProfileViewProjection(userId));
            
            // projektion validieren
            if (p is null) return View("~/Views/Errors/Error.cshtml",
                     new ErrorViewModel(404, $"Es wurde leider kein Profil mit der Id #{userId} gefunden.", null))
                     .WithStatusCode(HttpStatusCode.NotFound);

            // viewmodel erzeugen
            UserProfileViewModel vm = new UserProfileViewModel(p.Profile, p.Avatar, p.ForumStats, p.LatestActivity, p.LatestPost);
            // an die view übergeben
            return View(ViewsRoot + "UserProfile.cshtml", vm);
        }
(Ist ein echtes Beispiel)

Bitte keinen ViewBag für sowas verwenden; dafür ist der ViewBag nicht da.
ViewModels werden sauber als Parameter via View() übergeben.
Dokumentation dazu: ASP.NET Core - How controllers specify views

Wie man Logik auslagert hat ja Papst verlinkt.
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Meinst du jetzt ich solle den Datenzugriff komplett vom ASP.NET Projekt auslagern? Also es z.B. in eine DLL in der Projektmappe aussourcen?
Und von der dann aus mit nem ORM Mapper auf die DB zugreifen?

Oder meinst du die Modell, Controller, View innerhalb von ASP?
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Super okay! Der Post drüber bezog sich auf die Antwort von Papst

Mit was arbeite ich dann in der Bibliothek am besten? Entity Framework?

Moderationshinweis von Abt (10.03.2020 - 20:30:06):

Bitte keine Full Quotes

private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Es gibt nicht den pauschal einen Weg, wie man Quellcode outsourced.

Die Grundidee ist, dass Dein Code von jeder Art von Anwendung funktioniert und nutzbar ist; egal ob ASP.NET, WPF oder eine Konsolenanwendung.
Daher kann die Logik nicht Teil des Anwendungsprojekts sein.

Im .NET Umfeld gibts dafür die Klassenbibliotheken, die dann referenziert werden um sie dann in Anwendungen wie ASP.NET oder WPF zu nutzen.

Wenn Du Schichten ordentlich trennst und die Grundkonzepte von Laden von Modellen umsetzt, dann ergibst sich auch Dein Problem nicht mehr.
Denn letzten Endes entsteht das Lade-Problem, was Du hast, durch den Konzeptfehler.

Im Endeffekt ist mein Codesnippet was Du da siehst quasi die "maximale Ausbaustufe".
Halte Dich einfach an die Grundidee von [Artikel] Drei-Schichten-Architektur
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Nochmal kurz was zum Verständnis dazu:

Selbst wenn ich das in Schichten trenne löst das ja nicht mein Problem.
Ich greife ja dann nur auf den DbContext über eine DLL zu.

Also ist die eigentliche Lösung für das Problem:

Include(c => c.Orders)

Oder?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Schau Dir an, wie EF - und hier in diesem Falle Lazy Loading - funktioniert.

Include forciert Eager Loading, weil Du in Deiner aktuellen Implementierung kein Lazy Loading verwenden kannst. bzw. funktioniert es in dieser Form eben nicht.
Daher hat Dich Papst auch auf Include() hingewiesen, was Eager Loading bezweckt.

Der allgemein korrekte Weg wäre hier ohnehin das Vorgehen im Sinne von Eager Loading (Projektionen sind quasi auch Eager Loading), da ansonsten zig Calls gegen die Datenbank gehen (statt einem) und das entsprechend unperformant werden kann.

Aber wie gesagt: schau Dir die Funktionweise von EF an; nur dann hast Du auch ein Verständnis dazu.
Wenn man EF "irgendwie" entwickelt, dann endet das meist mit nem harten Knall gegen die Wand.
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Ok danke, nochmal zu den Schichten:

Test.Objects.dll - Objekte/Models mit denen gearbeitet wird
Test.Data.dll - Stellt den DbContext zur Verfügung
Test.Controller.dll - Stellt die Views,... zur Verfügung
Test.Host.dll - das eigentliche ASP.NET Projekt holt sich nur noch Views, etc. aus unteren Schichten

Wäre es so "nach Stand der Technik" richtig ein größeres Projekt zu strukturieren? Gibt es dazu irgendwo gute praktische Beispiele?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Die Auftrennung von Code in mehrere Projekte hat prinzipiell nichts mit der Problematik zutun.
Namespaces sind in C# ein Mechanismus um Code zu organisieren. Die Organisation richtet sich dabei nach der Verwendung; nicht nach der Aufspaltung in "Schichten".

Die Aufteilung in solche Dinge wie "Data" "Controller" "Objects" etc.. sind meistens ein Hinweis, dass man den Sinn von Namespaces noch nicht verinnerlicht hat, wozu diese eigentlich da sind.

Man könnte Deine gesame Problematik in einem eigenen Namespace organisieren und trotzdem alles sauber lösen.
Der Hinweis auf die Trennung in eine Klassenbibliothek diente Dir dazu, dass Du verstehst, was der Sinn in Code Organisation ist: dass Du den Code potentiell wiederverwenden kannst.

Eine weit verbreitete, simple Grundarchitektur bei ASP.NET ist:
- Repositories für das Laden von Daten (EF Core ist dabei bereits die Darstellung vom Repository Pattern)
- Services für die Business Logik
- Verwendung der Services in den Actions

In vielen Samples (es sind nur Beispiele!) sieht man die Verwendung der Repositories direkt in den Actions.
Damit spart man sich vor allem am Anfang natürlich etwas Code; oft hat man aber später dann redundanten Code in den Actions.

namespace Firmenname.Produkt.Models
{
    public class CustomerBusinessModel
    {

    }
}

namespace Firmenname.Produkt.Services
{
    public class CustomerService
    {
        private readonly IDbContext _dbContext;

        public CustomerService(IDbContext dbContect)
        {
            _dbContext = dbContect;
        }
        public async Task<IList<CustomerWithOrdersProjection>> GetCustomersWithOrders(int id)
        {
            // hier die logik um die Customers mit Ordern zu laden

            var customerEntities = await _dbContext.Customers.Include(c => c.Orders).Where()...ToListAsync() // 

            IList<CustomerWithOrdersProjection> customers = new List<CustomerWithOrdersProjection>()
                // Schleife und hier die Werte der Einträge in customerEntities in customers übertragen
                // Automapper kann dies auch automatisch machen

            return customers;
        }
    }

Diesen Service kannst Du dann in der Action aufrufen.

Allgemein aber nochmals Hinweise:
- Schau Dir mal die Konzepte in EF und ASP.NET Core an. Investier einfach mal 2 Tage in Doku lesen. Danach kommst Du auch viel schneller voran
- Der Bezeichner "Customer" suggeriert ein Business Model. Entitäten haben meist ein "Entity" Suffix. Entitäten sind einfach keine Business-Objekte, sondern nur Daten-Objekte.
private Nachricht | Beiträge des Benutzers
KroaX
myCSharp.de - Member

Avatar #avatar-4080.jpg


Dabei seit:
Beiträge: 315
Herkunft: Köln

beantworten | zitieren | melden

[offtopic]
Zitat
Wie aber Papst schon sagte musst Du ordentlich die Schichten trennen.

Haha ich hab gelesen: Wie der Papst schon sagte ....

Musste herzlich lachen weil ich den Gedanken übertragen habe auf "das Volk in Schichten zu trennen". Ich dachte echt es ist eine Floskel.
[/offtopic]
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Zitat von Abt

...

namespace Firmenname.Produkt.Services
{
    public class CustomerService
    {
        private readonly IDbContext _dbContext;

        public CustomerService(IDbContext dbContect)
        {
            _dbContext = dbContect;
        }
        public async Task<IList<CustomerWithOrdersProjection>> GetCustomersWithOrders(int id)
        {
            // hier die logik um die Customers mit Ordern zu laden

            var customerEntities = await _dbContext.Customers.Include(c => c.Orders).Where()...ToListAsync() // 

            IList<CustomerWithOrdersProjection> customers = new List<CustomerWithOrdersProjection>()
                // Schleife und hier die Werte der Einträge in customerEntities in customers übertragen
                // Automapper kann dies auch automatisch machen

            return customers;
        }
    }


Initalisiere ich den Service dann in der ASP.NET Anwendung?

Da registriert man ja eigentlich einen Kontext z.B. so:

    services.AddDbContext<SchoolContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

Also von wo aus würdest du deinen CustomerService erstellen?


Ich habe jetzt einmal das als Test.Common.Data:



    public class OrderContext : DbContext
    {
        public OrderContext(DbContextOptions<OrderContext> options) : base(options)
        {
        }

        public DbSet<Customer> Customers { get; set; }
        public DbSet<Orders> Orders { get; set; }
}

Nun erstelle ich eine ähnliche Service Funktion wie deine (mit GetAllOrders(), etc.), von wo initialisiere ich die jetzt?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von JimStark am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Der Service würde als Scoped* als im DI Container registeriert werden.
Dann kannst ihn in der Action als Ctor-Parameter empfangen.

*je nach Kontext auch Transient.
Aber auf keinen Fall als Singleton.
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Ok danke, werde ich versuchen.

Ich bin gerade noch dabei das erstmal ohne ASP auszubauen.

Folgendes Problem beim Service:


        public async Task<IList<Customer>> GetAllCustomers()
        {
            var Customers = await this._dbContext.Customers.Include(p=>p.Orders).ToListAsync();

            return Customers;
        }

Abruf:


            var customers = ts.GetAllCustomers();
            customers.Wait();
...
Wenn ich das Include weglasse geht es wunderbar, wenn ich es drin habe kommt folgender Fehler:
Fehler
InvalidOperationException: Lambda expression used inside Include is not valid.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von JimStark am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Wait() ist ein Anitpattern. Brauchst Du Wait() bei Tasks, dann machst Du was falsch.
async await falsch anzuwenden ist schlimmer als es nicht anzuwenden.

Der Fehler
Fehler
Lambda expression used inside Include is not valid.
kommt, wenn eine Eigenschaft kein Setter hat.
Wahrscheinlich hat Orders nur ein Getter.
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Danke! Hab wirklich den Setter vergessen.

Ich rufe das aktuell noch aus einer Konsolen Anwendung auf. Deswegen das mit dem Wait()
Wäre es jetzt ein ASP Projekt im Controller, wäre der Aufruf ja innerhalb eines Tasks, da müsste es dann wie bei dir aufgerufen werden:

var p = await _eventDispatcher.Send(new GetUserProfileViewProjection(userId));
oder?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Jo; aber auch mit Konsolenanwendungen kann man ordentlich async await umsetzen.

C# Main() Method - Async Main return values
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Zitat von Abt
Der Service würde als Scoped* als im DI Container registeriert werden.
Dann kannst ihn in der Action als Ctor-Parameter empfangen.

Also ich habe jetzt meinen Service mit Interface:


public interface ICustomerService{
      Task<IList<Customer>> GetAllCustomers();
}

Den Service registriere ich dann in der ASP Anwendung:


services.AddScoped<ICustomerService, CustomerService>();

Wie kann ich jetzt möglichst einfach vom Controller darauf zugreifen?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Siehe Blick in die Doku
Dependency injection into controllers in ASP.NET Core
Bitte vorher selbst mal die Dokusuche verwenden ;-)
Ist manchmal schneller gesucht als ein Beitrag geschrieben.
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Perfekt danke!

Falls jemand das gleiche Problem hat, mit Parameter:


services.AddTransient<ICustomerService>(s => new CustomerService(new CustomerContext()));

Noch eine Frage zu deinem Beispiel Code,
du erstellst den View dann auch in einer extra "Schicht" oder?
Also in der ASP Anwendung ist so zusagen außer den jeweiligen Funktionsaufrufen fast gar keine Logik?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Zitat von JimStark
services.AddTransient<ICustomerService>(s => new CustomerService(new CustomerContext()));

Das ist nicht gut.
Der Parameter sollte genauso registriert werden. Zudem solltest Dir überegen ob Du wirklich Transient brauchst oder doch nicht Scoped (vor allem beim Kontext).
Steht auch in der Doku. Nimm Dir bitte (endlich) Zeit sie zu lesen.
Zitat von JimStark
du erstellst den View dann auch in einer extra "Schicht" oder?
Was meinst Du damit?
Views sind an für sich ohnehin in ASP.NET Core entkoppelt (außer Du verwendest Razer Pages).
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Du meinst schon das hier oder?https://docs.microsoft.com/de-DE/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1

Scoped "lebt" dann solange wie der Client verbunden ist, ist dann mit Context schlauer?
Transient würde dann bei jedem Refresh einen neuen Context erstellen, hab ich das richtig verstanden?
private Nachricht | Beiträge des Benutzers
Papst
myCSharp.de - Experte



Dabei seit:
Beiträge: 362
Herkunft: Kassel

beantworten | zitieren | melden

Ein Client ist nicht verbunden in dem Sinne.
Bei HTTP gilt, die Verbindung des Clients ist ein Request. Danach ist er nicht mehr verbunden.

Scoped lebt über genau einen Request. Innerhalb eines Requests bekommst du immer die gleiche Instanz der Klasse.
Bei Transient bekommst du jedes mal eine neue Instanz.
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Ok, also ist scoped bzgl. Performance besser geeignet oder?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Puh.. Du magst wirklich keine Dokus lesen, oder?
Und ich mag Dir nicht die Doku vorlesen :-)

-> Eine Action kann mehrere Services haben, die jedoch prinzipiell technisch nicht nur an der Action selber sondern an vielen Stellen des Requests verwendet werden können.
-> Das gleiche gilt für den Kontext: ein Kontext kann / muss von vielen Services verwendet werden, zB. wegen Context Shared Informations.

Es kann daher zu Race Conditions, wenn jeder Service seinen eigenen Context bekommt bzw. wenn solche Dependencies nicht richtig registriert sind.
Es geht also nicht um Performance, sondern einfach um Logik. Es kommt daher durchaus an, wie man programmiert.

War nun auch mein letzter Hinweis dazu, da ich wie gesagt Dir nicht die Doku vorlesen mag.
Ist nicht Sinn der Sache.
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 255

Themenstarter:

beantworten | zitieren | melden

Ich versteh es nicht ganz :D

Also den Context dann als Singleton und den dann an den Service (Scoped) übergeben sodass es insgesamt nur einen Context gibt?
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15832
Herkunft: BW

beantworten | zitieren | melden

Les Dir durch was ein Singleton ist und Du weißt, warum das noch eine schlechtere Idee ist...
Du wirst nicht drum herum kommen Sachen zu lesen.

Liest Du nicht, dann knallt Dir alles - zurecht - um die Ohren.
private Nachricht | Beiträge des Benutzers