C# Datentypen „Owned“ & “ComplexType”

Alexander W. | Softwareentwickler
24/5/2024
Blog

[Owned] und [ComplexType] Datentypen in Entity Framework Core 8.0

[Owned] und [ComplexType] Datentypen sind fortgeschrittene Konzepte in Entity Framework Core, die es Entwicklern ermöglichen, komplexe Datentypen innerhalb von Entitäten zu verwalten. Diese Funktion erleichtert das Design von Datenmodellen und fördert Wiederverwendbarkeit und Modularität.

Was ist Ihre Botschaft?

Die Verwendung von [Owned] und [ComplexType] Datentypen in Entity Framework Core verbessert die Effizienz und Wartbarkeit von Datenmodellen. Sie ermöglichen es, komplexe Datentypen innerhalb von Entitäten zu strukturieren, wodurch wiederverwendbare und klar definierte Modelle entstehen. Ein Vorteil ist, dass diese Datentypen automatisch mit der übergeordneten Entität geladen werden und nicht explizit mit der .Include-Methode eingeschlossen werden müssen.

Was ist Ihre Zielgruppe?

Die Zielgruppe sind Softwareentwickler und Architekten, die mit .NET und Entity Framework Core arbeiten und nach fortgeschrittenen Techniken suchen, um ihre Datenmodelle zu optimieren. Besonders profitieren Entwickler, die große und komplexe Anwendungen erstellen, bei denen Modularität und Wiederverwendbarkeit von Datenmodellen entscheidend sind.

Durchführung

Implementierung von [Owned] und [ComplexType] Datentypen: Definition und Beispiel

Ein [Owned] und [ComplexType] Datentyp ist eine komplexe Datenstruktur, die einer Entität zugeordnet ist und nicht eigenständig existiert. Ein häufiges Beispiel ist eine Adresse, die als Teil einer Bestellung oder eines Distributors modelliert wird.

[Owned] Datentyp StreetAddress

1[Owned]
2public class StreetAddress 
3{
4    public string? Street { get; set; }
5    public string? City { get; set; }
6}

Code-Beispiel: Order und StreetAddress

1public class Order 
2{
3    public int Id { get; set; }
4    public string? Name { get; set; }
5    public StreetAddress? ShippingAddress { get; set; }
6    public StreetAddress? BillingAddress { get; set; }
7}
8
9protected override void OnModelCreating(ModelBuilder modelBuilder) 
10{
11    // Owned Demo
12    modelBuilder.Entity<Order>()
13        .OwnsOne(p => p.ShippingAddress, od => 
14        {
15            od.ToTable("OrderShippingsAddress");
16        });
17}

In diesem Beispiel wurde die ShippingAddress als eigene Tabelle über den DbContext definiert, während die BillingAddress nicht separat behandelt wurde.

Code-Beispiel: Distributor und ShippingCenters

Ein weiteres Beispiel ist ein Distributor, der mehrere Versandzentren hat:

1public class Distributor 
2{
3    public int Id { get; set; }
4    public string? Name { get; set; }
5    public StreetAddress? HeadquarterAddress { get; set; }
6    public ICollection<StreetAddress> ShippingCenters { get; set; }
7
8    public Distributor() 
9    {
10        ShippingCenters = new List<StreetAddress>();
11        HeadquarterAddress = new StreetAddress();
12    }
13}

Hier werden die ShippingCenters automatisch als separate Tabelle implementiert, ohne explizite Konfigurationen im DbContext.

[ComplexType] Datentyp Address

1[ComplexType]
2public class Address 
3{
4    public string Street { get; set; }
5    public string City { get; set; }
6    public string State { get; set; }
7    public string PostalCode { get; set; }
8}

Code-Beispiel: Person und Address

1public class Person 
2{
3    public int Id { get; set; }
4    public string FirstName { get; set; }
5    public string LastName { get; set; }
6    public Address HomeAddress { get; set; }
7    public Address DeliveryAddress { get; set; }
8
9    public Person() 
10    {
11        HomeAddress = new Address();
12        DeliveryAddress = new Address();
13    }
14}
15
16protected override void OnModelCreating(ModelBuilder modelBuilder) 
17{
18    // Owned Demo
19    modelBuilder.Entity<Person>()
20        .OwnsOne(p => p.HomeAddress, od => 
21        {
22            od.ToTable("PeopleHomeAddress");
23        });
24}

Hier wurde die HomeAddress als separate Tabelle über den DbContext definiert, während die DeliveryAddress nicht.

Abschluss/ Zusammenfassung

Vorteile von [Owned] und [ComplexType] Datentypen:

  • Modularität: Die Definition komplexer Datentypen innerhalb von Entitäten führt zu modularerem und besser organisiertem Code. Eigene Tabellen mit FK-Beziehungen können weiterhin über den DbContext konfiguriert werden.
  • Wiederverwendbarkeit: Dieselben Datentypen können in mehreren Entitäten wiederverwendet werden, was die Konsistenz und Wartbarkeit erhöht.
  • Automatisches Laden: Diese Datentypen werden automatisch mit der übergeordneten Entität geladen und müssen nicht explizit mit .Include eingeschlossen werden.

Nachteile von [Owned] Datentypen:

Begrenzte Flexibilität: [Owned] Datentypen können nicht unabhängig von ihrer übergeordneten Entität gespeichert werden. Ein Fehler tritt auf, wenn versucht wird, einen Owned-Datentyp ohne die zugehörige Entität zu speichern.

Vergleich zu [ComplexType] in EF Core 8.0:

Ähnlichkeiten:

Beide Konzepte fördern Modularität und Wiederverwendbarkeit, indem sie wiederverwendbare Datentypen definieren und innerhalb von Entitäten nutzen.

Unterschiede:

  • Flexibilität: [ComplexType] bietet mehr Flexibilität, da diese nicht immer an eine übergeordnete Entität gebunden sind.
  • Ladesteuerung: [ComplexType] erlaubt mehr Kontrolle darüber, wann und wie diese geladen werden, was zu effizienteren Abfragen führen kann.
  • Lebensdauerverwaltung: [ComplexType] können unabhängiger verwaltet werden.

Alexander W. | Softwareentwickler
Zurück zur Übersicht

Gemeinsam Großes schaffen

Wir freuen uns auf ein kostenloses Erstgespräch mit Ihnen!
Unser Geschäftsführer Tibor Csizmadia und unser Kundenbetreuer Jens Walter stehen Ihnen persönlich zur Verfügung. Profitieren Sie von unserer langjährigen Erfahrung und erhalten Sie eine kompetente Erstberatung in einem unverbindlichen Austausch.
Foto von Tibor

Tibor Csizmadia

Geschäftsführer
Foto von Jens

Jens Walter

Projektmanager
Devware GmbH verpflichtet sich, Ihre Privatsphäre zu schützen. Wir benötigen Ihre Kontaktinformationen, um Sie bezüglich unserer Produkte und Dienstleistungen zu kontaktieren. Mit Klick auf Absenden geben Sie sich damit einverstanden. Weitere Informationen finden Sie unter Datenschutz.
Vielen Dank für Ihre Nachricht!

Wir haben Ihre Anfrage erhalten und melden uns in Kürze bei Ihnen.

Falls Sie in der Zwischenzeit Fragen haben, können Sie uns jederzeit unter [email protected] erreichen.

Wir freuen uns auf die Zusammenarbeit!
Oops! Something went wrong while submitting the form.
KontaktImpressumDatenschutz