5

I 5. Datenbank zuerst mit Entity Framework bin Wir haben zwei Tabellen (massiv vereinfacht):Wie Ändern Navigation Eigenschaftsnamen in bedeutungsvollen Namen

  • Adressen
    • Straße
    • Town (etc .)
  • Kunden
    • Namen
    • Rechnungsanschrift
    • deliveryaddress
    • AltDeliveryAddress

Wenn wir Visual Studio verwenden, um die Datenbank in EF ("Update Modell aus der Datenbank") zu importieren, wir mit dem Code am Ende wie folgt:

Customer myCustomer; 
var a = myCustomer.Address; 
var b = myCustomer.Address1; 
var c = myCustomer.Address2; 

Was ich natürlich will, ist so etwas wie dieses:

var a = myCustomer.BillingAddress; 
var z = myCustomer.BillingAddress.Street; // etc. 

Ich könnte einfach das Modell im Designer bearbeiten und die Navigationseigenschaft ändern, um mir den richtigen Namen zu geben. Dies ist jedoch keine praktikable Lösung, da wir das Modell jedes Mal neu erstellen, wenn wir Änderungen an der Datenbank vornehmen.

Eine Option, die ich versucht habe, ist eine partielle Klasse wie folgt zu schaffen (Code aus bestehenden MyModel.Designer.cs kopiert nur mit dem Eigenschaftsnamen geändert):

public partial class Customer : EntityObject 
{ 
    [EdmRelationshipNavigationPropertyAttribute("MyModel", "FK_Customers_Addresses_BillingAddress", "Address")] 
    public Address BillingAddress 
    { 
     get { 
      return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<LookupItem>("MyModel.FK_Customers_Addresses_BillingAddress", "Address").Value; 
     } 
     set { 
      ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<LookupItem>("MyModel.FK_Customers_Addresses_BillingAddress", "Address").Value = value; 
     } 
    } 
} 

Jedoch, wenn ich diese laufen, bekomme ich der folgende Fehler:

The number of members in the conceptual type 'MyModel.Customer' does not match with the number of members on the object side type 'MyNamespace.DataModel.Customer'. Make sure the number of members are the same.

Ich habe versucht, mit dem Attribut [NotMapped()], aber das hat keinen Unterschied gemacht. Wenn ich das entfernen [EdmRelationshipNavigationPropertyAttribute ...] Attribut dann die Linq mit dem folgenden Fehler klagt:

The specified type member 'BillingAddress' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

Gibt es eine andere Art und Weise aussagekräftige Namen zu erreichen, in der Kunden-Objekt?

Hier ist, was ich am Ende wollen:

var j = myCustomer.BillingAddress; 
var k = myCustomer.BillingAddress.Street; 
var l = myCustomer.BillingAddress.Town; // etc. 

Antwort

2

Sie können Objekte zu Ihrer Teil-Klasse hinzufügen, die Accessoren Eigenschaften Address1, Address2 usw.

Beispiel sein:

public partial class Customer : EntityObject 
{ 
    public Address BillingAddress 
    { 
     get 
     { 
      return this.Address; 
     } 
     set 
     { 
       this.Address = value; 
     } 
    } 
} 

Update: Es wird nicht mit Linq zu Entitäten arbeiten. Ich fürchte, das ist die Beschränkung der Datenbank ersten Ansatz. Es ist eine der Ursachen für uns, EF Code First zu verwenden. In Code First haben Sie die volle Kontrolle über die Entity Mapping.(Code First bedeutet das Mappen im Code, es bedeutet nicht, dass Ihre db aus diesem Code generiert wird, wenn Sie es nicht wollen).

+0

Das funktioniert, wenn Sie sicher sein können, die Zuordnung zwischen EF generierten Namen und den tatsächlichen Datenbanknamen zu gewährleisten. , d. H. Wenn .Address2 immer AltDeliveryAddress ist, dann ist das in Ordnung, aber es scheint nicht sehr sicher. – andrewpm

+0

Eigentlich nein, das funktioniert nicht, wenn ich versuche, es in LINQ zu verwenden. Hier ist mein Code: var customersInSeattle = cs.Where (c => c.DeliveryAddress.Town == "Seattle"); Ich erhalte diesen Fehler: Der angegebene Typ member 'DeliveryAddress' wird in LINQ to Entities nicht unterstützt. Es werden nur Initialisierungs-, Entitäts- und Entitätsnavigationseigenschaften unterstützt. – andrewpm

+0

Ja, es ist wahr ... Ich fürchte, das ist eine Einschränkung der Datenbank zuerst Ansatz. Es ist eine der Ursachen für uns, EF Code First zu verwenden. In Code First haben Sie die volle Kontrolle über die Entity Mapping. (Code First bedeutet das Mappen im Code, es bedeutet nicht, dass Ihre db aus diesem Code generiert wird, wenn Sie es nicht wollen). –

3

Sie wahrscheinlich müssen nicht kümmern. Nach dem Ändern des Eigenschaftsnamens im Modelldesigner merkt sich EF die benutzerdefinierte Benennung. Es wird nicht durch nachfolgende Aktualisierungen überschrieben.

+2

Nun, es funktioniert nur so lange, wie Sie die Entität nicht entfernen und es in Ihr Modell einlesen, was passieren kann, wenn Sie Ihr Modell mit der Datenbank synchronisieren möchten. f. das Löschen einer Spalte in der Datenbank führt in Ihrem Modell beim Aktualisieren nicht dazu – KroaX

+2

Leider ist der EF-Designer nicht so zuverlässig. Oft löschen wir einfach das gesamte Modell und erstellen es neu, da das Ausführen von Aktualisierungen es bricht. Daher ist diese Option für uns nicht verfügbar. – andrewpm

+0

Wenn ich Änderungen am Modell vornehme, wird es auch die entsprechenden Änderungen an vorhandenen Datenbank- und Codeklassen vornehmen? ... das will ich wirklich. –

0

Ich weiß, das ist ein bisschen alt, aber es scheint der einfachste/beste Weg, um mit dieser Situation umzugehen, ist das EF5 Power-Tool "Reverse-Engineering-Code zuerst."

http://msdn.microsoft.com/en-us/data/jj200620

Es gibt Ihnen alle Vorteile von Code erster Mappings mit der Einfachheit/Bequemlichkeit der Datenbank ersten Objekterstellung.

0

gibt es eine Lösung, die hier beschrieben:

Improve navigation property names when reverse engineering a database

Sie können die Codegenerierung Vorlagen enthalten in Ihr Projekt (* tt-Dateien.). Ändern Sie sie so, wie es auf dem Link beschrieben ist. Beispiel ist hier: https://github.com/markuspeter/EFPowerToolsTemplates (überprüfen Sie Filialen für Änderungen)

Dann kann Ihre Benennung mit besseren Namen generiert werden.

+1

Es wird immer empfohlen, Codeschnipsel/am besten geeigneten Absatz oder zwei von der verknüpften Ressource zu verwenden, auch wenn nur Linkverrottung verhindert wird. – bardzusny