2017-11-08 5 views
0

Ich habe eine Datenbank in SQL Server erstellt und Entity Framework verwendet, um ein Modell in meinem C# MVC 5-Projekt zu erstellen. In meinen Modellen verwende ich System.ComponentModel, um einem DisplayName mehrere Eigenschaften (oder Spalten) zuzuweisen. Beispiel:Present DisplayName zwischen Coderegenerierung

namespace ProjectTracking.Models 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel; 

    public partial class EmployeeType 
    { 
     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
     public EmployeeType() 
     { 
      this.Employees = new HashSet<Employee>(); 
     } 

     [DisplayName("Employee Type ID")] 
     public int PK_EmployeeTypeID { get; set; } 

     [DisplayName("Employee Type Name")] 
     public string EmployeeTypeName { get; set; } 

     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
     public virtual ICollection<Employee> Employees { get; set; } 
    } 
} 

Das Problem, das ich habe laufen in ist, dass, wenn ich die Datenbank aktualisieren und mein Modell aktualisieren, verliere ich alle diese Informationen als alle Modellklassen regeneriert werden. Gibt es eine Möglichkeit, diese Informationen zu erhalten?

+3

'' [Name] '' ist eine Ansicht bestimmtes Attribut durchgeführt werden und sollte zu Ihrer Ansicht Modelle angewendet werden, nicht Ihre Datenmodelle ([Was ist Ansichtsmodell in MVC ?] (https://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc)). Und als Randnotiz verwenden Sie '[Display (Name =" ... ")]]' statt '[DisplayName]' ([Attribut Anzeigename gegen Anzeigeattribut] (https://stackoverflow.com/questions/5243665/Anzeigename -attribute-vs-display-attribute)) –

Antwort

2

EF verwendet T4-Vorlagen, um den Code zu generieren. Sie sollten diese Dateien niemals bearbeiten, da sie beim Öffnen des Designers jederzeit neu generiert werden können.

Es gibt einen Weg, dies zu tun, mit der MetadataTypeAttribute `

EF die Modelle als Teilklassen erzeugt, so können Sie einen anderen Teil in einer anderen Datei hinzufügen, die nicht regeneriert werden und die MetadataTypeAttribute zu es. Dies wird auf eine weitere Klasse verweisen, in der Sie die Eigenschaften duplizieren und die DisplayNameAttribute liefern können. Wie folgt aus:

[MetadataType(typeof(EmployeeTypeMetaData))] 
public partial class EmployeeType { } 

public class EmployeeTypeMetaData 
{ 
    [Required(ErrorMessage = "Title is required.")] 
    public object Title; 

    // etc 
} 

Dies würde den Job ... Aber:

Sie sollten dies nicht verwenden aus den folgenden Gründen:

  • Dies gibt Ihnen einen Wartungs Alptraum. Jedes Mal, wenn sich Ihr Modell ändert, müssen Sie auch die Metadaten ändern.
  • Sie sollten Ihre ef-Modelle niemals direkt in Ansichten verwenden. Verwenden Sie DTO Objekte dazwischen und ordnen Sie zwischen den ef-Modellen und dem DTO zu. Mapping kann entweder von Hand aus durch ein Werkzeug wie AutoMapper
+0

Kennen Sie eine gute Quelle, wo ich mehr über DTO lesen kann? – DForck42

+1

[Dies] (https: //www.exceptionnotfound.net/entity-framework-und-wcf-mapping-entities-to-dtos-with-automapper /) scheint ein solider Artikel auf einer schnellen Google-Suche. Ich würde jedoch empfehlen, mit der manuellen Zuordnung zu beginnen, bevor Sie AutoMapper verwenden, um den Zuordnungsprozess wirklich zu verstehen und wo die Vorteile liegen. AutoMapper kann als Zauberstab fungieren, wenn Sie den Prozess nicht wirklich verstehen. –

+0

@ Ric.Net Besonders wenn Lazy Loading eingeschaltet ist, kann der Automapper die Systeme stark beeinträchtigen. –

1

Ihre beste Option besteht darin, Entity Framework-Entitäten nicht direkt als Ansichtsmodelle zu verwenden. Erstellen Sie stattdessen Ansichtsmodelle, die darstellen, was angezeigt werden muss, und ordnen Sie die Werte der Entitäten den Ansichtsmodellen zu (mit AutoMapper wird dies zu einem Kuchenspaziergang).

Was meinst du mit "direkt als Ansicht Modelle"

Ihr Code sieht wie wahrscheinlich wie:

public class MyContextDb 
{ 
    public DbSet<EmployeeType> EmployeeTypes { get; set; } 
} 

public class MyController 
{ 
    public ActionResult Index() 
    { 
    using (var db = new MyDbContext) 
    { 
     var emp = db.EmployeeTypes.FirstOrDefault(); 
     return View(emp); // <-- passing EF entity as view model 
    } 
    } 
} 

Statt

public EmployeeTypeVM 
{ 
    // Properties you want to expose and annotate 
} 

    using (var db = new MyDbContext) 
    { 
     var emp = db.EmployeeTypes.FirstOrDefault(); 
     var vm = Mapper.Map<EmployeeTypeVM>(emp); 
     return View(vm); // <-- passing view model 
    } 

ich diesen Ansatz immer empfehlen wie Sie nicht normalerweise das emp, nur das vm mit Logik und einem versehentlichenändernwirkt sich nicht auf echte Daten aus.

+0

Ich lerne immer noch alles. Was od meinst du mit "direkt als Models"? – DForck42

Verwandte Themen