Laden...

Via Methodensyntax Daten aus EF mit LINQ abfragen

Erstellt von mchrd vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.019 Views
M
mchrd Themenstarter:in
17 Beiträge seit 2018
vor 5 Jahren
Via Methodensyntax Daten aus EF mit LINQ abfragen

Hallo zusammen,

ich habe eine Frage zur Abfragesyntax und Methodensyntax in LINQ. Ich habe in der Datei mal eine fiktives Datenbankschema erstellt. Wenn ich dieses mittels Entity Framework Core umsetzen wollte könnte ich z. B. mittels LINQ abfragen erstellen.

Wenn ich folgende Abfrage erstellen möchte "Welche Bücher hat Author 1 und zu welchen Kategorien gehören die jeweiligen Bücher" würde ich eine solche Abfrage per Abfragesyntax in LINQ hinbekommen.

Allerdings würde ich die gleiche Abfrage gerne einmal mit der Methodensyntax realisieren. Hierzu habe ich folgende Frage:

Wenn ich die Abfrage in der Abfragensyntax erstelle Joine ich Tabellen. Ich habe jedoch Beispiele gesehen, bei denen mittels **Expand **(oData) oder **Include **Daten abgefragt werden.

Besteht die Möglichkeit, dass man** ohne ein Join über die Navigation Properties** eine Abfrage erstellt, welche zu einem Author die Bücher mit der jeweiligen Kategorie ausgibt ohne dass man sagen muss, welche Daten zu Joinen sind?

Ich hoffe ich habe meine Frage verständlich ausgedrückt. Wenn nicht würde ich Code erstellen.

Danke fürs Lesen und für die Hilfe vorab!

5.657 Beiträge seit 2006
vor 5 Jahren

Deine Erklärung paßt nicht zu dem angehängten Schema, ich versuche es trotzdem:

"Welche Bücher hat Author 1 und zu welchen Kategorien gehören die jeweiligen Bücher"

var booksOfAuthorX = context.Books
  .Where(m => m.AuthorId == authorX.Id)
  .ToList();
var categoriesOfAuthorX = context.Books
  .Where(m => m.AuthorId == authorX.Id)
  .Select(m => m.Category)
  .Distict()
  .ToList();

.

Weeks of programming can save you hours of planning

M
mchrd Themenstarter:in
17 Beiträge seit 2018
vor 5 Jahren

Hallo MrSparkle,

vielen Dank für deine Antwort! Ja leider habe ich mich nicht richtig ausgedrückt um das rüber zu bringen was ich meine. Ich habe daher nochmal ein neues Modell in EFC erstellt:

    public class Child //Kind
    {
        public int ChildId { get; set; }
        public string Childname { get; set; }
        public ICollection<ChildPeople> ChildPeoples { get; set; }
    }

    public class ChildPeople
    {
        public int ChildId { get; set; }
        public Child Child { get; set; }
        public int PersonId { get; set; }
        public Person Person { get; set; }
    }

    public class Person // Eltern/Person
    {
        public int PersonId { get; set; }
        public string Personname { get; set; }
        public ICollection<ChildPeople> ChildPeoples { get; set; }
        public ICollection<PersonDivision> PersonDivisions { get; set; }
    }

    public class PersonDivision
    {
        public int PersonId { get; set; }
        public Person Person { get; set; }
        public int DivisionId { get; set; }
        public Division Division { get; set; }
    }

    public class Division //Abteilung
    {
        public int DivisionId { get; set; }
        public string DivisionName { get; set; }
        public ICollection<PersonDivision> PersonDivisions { get; set; }
        public ICollection<DivisionProduct> DivisionProducts { get; set; }
    }

    public class DivisionProduct
    {
        public int DivisionId { get; set; }
        public Division Division { get; set; }
        public int ProductId { get; set; }
        public Product Product { get; set; }
    }

    public class Product // Produkte
    {
        public int ProductId { get; set; }
        public string Productname { get; set; }
        public ICollection<DivisionProduct> DivisionProducts { get; set; }
        public ICollection<ProductCategory> ProductCategories { get; set; }
    }

    public class ProductCategory
    {
        public int ProductId { get; set; }
        public Product Product { get; set; }
        public int CategoryId { get; set; }
        public Category Category { get; set; }
    }

    public class Category // (Produkt-)Kategorien
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
        public ICollection<ProductCategory> ProductCategories { get; set; }
    }

Dieses Modell habe ich konstruiert (ohne dass es einen realen Zusammenhang gibt). Wichtig war mir, dass ich über einige m:n Beziehungen wandern muss.

Würde ich Include oder Extend verwenden um folgende Frage zu beantworten bzw. wie würde eine effiziente Abfrage in Methodenschreibweise aussehen?

Wer sind die Eltern von Kind 1, in welcher Abteilung arbeiten Sie, welche Produkte stellt diese Abteilung her und zu welcher Kategorie gehören diese?

Das Ergebnis würde ich als Tabelle ausgeben wollen (wenn es mehrere Eltern gibt, dann gäbe es zwei Zeilen).
Childname | Personname | DivisionName | Productname | CategoryName

Tut mir leid, dass ich das noch nicht wirklich verstanden habe wie man sinnvoll Abfragen erstellt (mittels Join in Abfragesyntax würde ich diese Abfrage hinbekommen) jedoch möchte ich auch verstehen wofür z. B. SelectMany, Include, Extend eingesetzt werden können.

Ich wünsche euch einen schönen Abend!

5.657 Beiträge seit 2006
vor 5 Jahren

Du hast zwei Möglichkeiten, auf EF-Navigationseigenschaften zuzugreifen, unabhängig davon, ob es sich um n:m-Beziehungen handelt:

  1. Einfach darauf zugreifen. Der EF lädt die Daten bei Bedarf nach. Das kann je nach Anwendungsfall performanter sein oder nicht.

  2. Mittels Include direkt bei der Abfrage mitladen. EF erstellt das passende SQL inkl. JOINs automatisch. Die generierten SQL-Befehle kannst du dir auch anzeigen lassen, was die Optimierung einfacher macht.

Mit SelectMany kannst du mehrdimensionale Auflisten in eindimensionale Auflistungen umwandeln, auch flatten genannt:

List<Person> persons = /* ... */;
List<Person> children = persons
  .SelectMany(m => m.ChildPeople) 
  .Select(m => m.Person)
  .ToList();

Weeks of programming can save you hours of planning

M
mchrd Themenstarter:in
17 Beiträge seit 2018
vor 5 Jahren

Hi MrSparkle,

vielen Dank für die Hilfe! Ich hab es hinbekommen! Sorry, dass ich mich erst so spät zurück gemeldet habe, aber ich habe noch einiges selbst ausprobiert.

Insbesondere der Tipp sich das generierte SQL anzeigen zu lassen war super! Danke!