2016-05-16 5 views
3

Ich bin neu in C# und .NET. Ich lerne ASP.NET MVC 5. Eine Sache, die ich selbst verbringen verbringen zusätzliche Zeit bei der Umwandlung eines Modells zu einem Viewmodel.Gibt es eine Verknüpfung, um ein Modell in ein Ansichtsmodell zu konvertieren?

Hier ist mein Modell

public class Overview 
{ 

    public string chain_name { get; set; } 
    public int store_id { get; set; } 
    public int total_attempts { get; set; } 
    public int total_unique_number_called { get; set; } 
    public int total_callable { get; set; } 
    public int total_completed_interviews { get; set; } 

} 

und hier ist meine Ansicht Modell

public class OverviewViewModel 
{ 

    public string chain_name { get; set; } 
    public int store_id { get; set; } 
    public int total_attempts { get; set; } 
    public int total_unique_number_called { get; set; } 
    public int total_callable { get; set; } 
    public int total_completed_interviews { get; set; } 
    public decimal? unique_number_per_complete { get; set; } 

    public OverviewViewModel() 
    { 
     unique_number_per_complete = 0; 
    } 

} 

, wie Sie beiden Modelle sehen und Ansichtsmodell sind identisch mit Ausnahme über Variable, die eine Berechnung ist.

Zu meiner Ansicht Modell bevölkern ich folgendes

var records = conn.Database.SqlQuery<Overview>(query).ToList(); 

var overView = new List<OverviewViewModel>(); 

foreach(var record in records){ 

    var newRecord = new OverviewViewModel(); 

    newRecord.store_id = record.store_id; 

    newRecord.chain_name = record.chain_name; 

    newRecord.total_attempts = record.total_attempts; 

    newRecord.total_callable = record.total_callable; 

    newRecord.total_completed_interviews = record.total_completed_interviews; 

    if (record.total_completed_interviews > 0) { 
     newRecord.total_unique_number_called = record.total_unique_number_called/record.total_completed_interviews; 
    } 

    overView.Add(newRecord); 
} 

Die beiden Fragen haben, die ich mit meinem Ansatz sehe, dass

  1. ist, ich habe zu tun, viele zusätzliche Codierung insbesondere der Ansicht, Modell ist groß oder f Ich habe mehrere Variablen, die ich berechnen muss.
  2. Ich fühle, dass ich 1 zusätzliche Zeit Schleife um mein Modell in den Ansichtsmodus zu konvertieren.

Gibt es einen einfacheren Weg, dies in C# zu tun?

Gibt es einen besseren Ansatz für dieses Verfahren für eine große Anwendung? Mein Ziel ist es, den besseren Weg zu lernen, meine Codezeit optimal zu nutzen.

+3

AutoMapper kann mit dem trivialen Mapping helfen. – user2864740

+0

Beachten Sie, Automapper ist sehr langsam, wenn Sie eine große Menge von Daten tp-Prozess haben, denken Sie an eigene benutzerdefinierte Mapper [Link] http://StackOverflow.com/Questions/4131720/Automapper-Running-Extremely-Slow-on-Mapping -1400-records – Thakur

Antwort

3

Ja, Sie sollten Automapper verwenden, Paketansicht Nuget installieren. Automapper ist auch sehr konfigurierbar.

http://automapper.org/

Erstellen Sie zunächst diese Klasse:

public static class AutoMapperConfig 
{ 
    public static void RegisterMappings() 
    { 
     //Example here, creates "two way" for Overview & OverviewViewModel mapping 
     Mapper.CreateMap<Overview, OverviewViewModel>(); //<source, destination> 
     Mapper.CreateMap<OverviewViewModel, Overview>(); //<source, destination> 
     //..more mapping for other Models and ViewModels. 
    } 
} 

In Global.asax.ApplicationStart() fügen Sie diese Zeile:

AutoMapperConfig.RegisterMappings() 

Jetzt Ihr foreach Beispiel in Ihren Kommentaren ist schön und einfach:

foreach (var record in records) 
{ 
    var newRecordOverviewViewModel = Mapper.Map<OverviewViewModel>(record); //<destination>(source) 
    overView.Add(newRecordOverviewViewModel); 
} 
+0

Vielen Dank Brian. Ich habe AutoMapper gerade in meinem Projekt installiert. Ich versuche zu verwenden, indem ich mein Overview-Objekt in OverviewViewModel-Objekt konvertiere. Wenn das wirklich ist, was ich brauche, werde ich deine Antwort akzeptieren. Ich bin mir nicht sicher, ob Sie einen kurzen Code haben, dem ich folgen sollte, um die zwei Objekte zu konvertieren, aber wenn Sie das tun, wird mir das helfen. Danke :) –

+0

Macht es Ihnen etwas aus, mir bei der Syntax zu helfen? Dies ist, was ich getan habe, aber ich bekomme currly lesen Zeilen in den 2 Objekten, die ich versuche, foreach (var Datensatz in Aufzeichnungen) zuordnen { \t OverviewViewModel newRecord = new OverviewViewModel(); \t var config = neue MapperConfiguration (cfg => cfg.CreateMap ()); \t var mapper = config.CreateMapper(); \t var final = Mapper.Map (Datensatz); \t overView.Add (endgültig); } ' –

+0

Wenn ich jetzt an der Syntax arbeite, kann ich dir sagen, dass du KEINE MapperConfiguration in der foreach-Schleife erstellst, wie du es tust, du machst das nur einmal in deinem Global.asax. Wird die Antwort für Sie aktualisieren. –

4

Ich stimme zu, dass Sie in AutoMapper suchen sollten, aber eine andere Möglichkeit wäre, einen Konstruktor in Ihrem OverviewViewModel-Modell zu erstellen, der ein Overview-Objekt übernimmt und alle Eigenschaften auffüllt. So etwas wie

public class OverviewViewModel { 

    public string chain_name { get; set; } 
    public int store_id { get; set; } 
    public int total_attempts { get; set; } 
    public int total_unique_number_called { get; set; } 
    public int total_callable { get; set; } 
    public int total_completed_interviews { get; set; } 
    public decimal? unique_number_per_complete { get; set; } 

    public OverviewViewModel() 
    { 
     unique_number_per_complete = 0; 
    } 
public OverviewViewModel(Overview record) 
    { 
     store_id = record.store_id; 

    chain_name = record.chain_name; 

    total_attempts = record.total_attempts; 

    total_callable = record.total_callable; 
    //etc 
    } 
} 

Dann würde der Code aussehen

var overView = new List<OverviewViewModel>(); 

foreach(var record in records){ 
    overView.Add(new OverViewViewModel(record)); 
} 
+0

+1 Sehr guter Punkt! Ich werde das trotzig berücksichtigen. Aber zuerst möchte ich den Autoadapter zum Arbeiten bringen, da es der beste Ansatz zu sein scheint. –

+0

Ich würde auch denken, dass die Verwendung von Auto Mapper in diesem Konstruktor großartig ist, meinen Code zu verkürzen, anstatt jede Variable aufzulisten, die lang werden kann. –

0

Eine weitere Alternative ist Linq und Erweiterungsmethoden zu verwenden, unter

using System.Collections.Generic; 
using System.Linq; 
using App.Data.Entities; 
using App.Business.Models; 

namespace App.Business 
{ 
    public static partial class OverviewAdapter 
    { 
     public static OverviewViewModel ToOverviewViewModel(this Overview overview) 
     { 
      return new OverviewViewModel 
      { 
       chain_name     = overview.chain_name, 
       store_id     = overview.store_id, 
       total_attempts    = overview.total_attempts, 
       total_unique_number_called = overview.total_unique_number_called, 
       total_callable    = overview.total_callable, 
       total_completed_interviews = overview.total_completed_interviews, 
       unique_number_per_complete = 0 
      }; 
     } 

     public static IEnumerable<OverviewViewModel> ToOverviewModelList(this IEnumerable<OverviewViewModel> overviewList) 
     { 
      return (overviewList != null) ? overviewList.Select(a => a.ToOverviewViewModel()) : new List<OverviewViewModel>(); 
     } 

     // Reverse - ToOverview/ToOverviewList if needed... 
    } 
} 

nun zu jeder Zeit Ihre Business-Klasse ist in Umfang, Sie haben eine erkennbare Methode für die Klasse und die Liste der Klasse, die hinzugefügt werden kann in der Reihe.

var records = conn.Database.SqlQuery<Overview>(query).ToOverviewModelList().ToList(); 

Dieser funktionellere Ansatz ist intuitiv, rationalisiert und Sie haben sofortiges Feedback, wenn ein Adapter noch nicht geschrieben wurde.

Es ist eine persönliche Präferenz, ob ein IEnumerable oder eine List von der Listenversion zurückgegeben wird. Der breitere IEnumerable ist die konventionellere Lösung, aber ich gehe die ganze Zeit von der Liste <> zu der Liste <> und der Verzicht auf IEnumerable scheint überflüssig zu sein.

Verwandte Themen