2016-05-16 91 views
3

我是新來的c#和.NET。我正在學習ASP.NET MVC 5.我發現自己花費額外的時間將模型轉換爲視圖模型。是否有將模型轉換爲視圖模型的快捷方式?

這裏是我的模型

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; } 

} 

,這裏是我的視圖模型

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; 
    } 

} 

,你可以看到兩個模型和視圖模型是相同的,除了以上變量,它是一個計算。

要填充我的視圖模型我下面

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); 
} 

,我用我的方法看到的兩個問題是,

  1. 我必須做很多額外的編碼尤其是考慮到模型是大的或f我有多個變量,我需要計算。
  2. 我覺得我循環1額外的時間將我的模型轉換爲視圖模式。

在c#中有更簡單的方法嗎?

對於大型應用程序,此過程有更好的方法嗎?我的目標是要學習更好的方式來充分利用我的代碼時間。

+3

AutoMapper可以幫助簡單映射。 – user2864740

+0

請注意,Automapper是非常慢,如果你有大量的數據tp過程,想想自己的自定義映射器[鏈接] http://stackoverflow.com/questions/4131720/automapper-running-extremely-slow-on-mapping -1400-records – Thakur

回答

3

是的,你應該使用Automapper,安裝包視圖Nuget。 Automapper也是非常可配置的。

http://automapper.org/

首先,創建這個類:

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. 
    } 
} 

在Global.asax.ApplicationStart()加入這一行:

AutoMapperConfig.RegisterMappings() 

現在您的評論你的foreach的例子就是很好的簡單:

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

非常感謝Brian。我剛剛在我的項目中安裝了AutoMapper。我試圖通過將我的Overview對象轉換爲OverviewViewModel對象。如果這真的是我需要的,我會接受你的答案。我不確定你是否有一段簡短的代碼來轉換這兩個對象,但如果你這樣做會幫助我一堆。謝謝:) –

+0

你介意幫助我的語法?這就是我所做的,但是我正在閱讀的線條是我試圖映射的兩個對象'foreach(記錄中的var記錄){ \t OverviewViewModel newRecord = new OverviewViewModel(); \t var config = new MapperConfiguration(cfg => cfg.CreateMap ()); \t var mapper = config.CreateMapper(); \t var final = mapper.Map (record); \t overView.Add(final); }' –

+0

現在處理語法,我可以告訴你,你不會像在做的那樣在foreach循環中創建一個MapperConfiguration,你只需在Global.asax中做一次。將爲您更新答案。 –

4

我同意你應該看看automapper,但另一種方法是在你的OverviewViewModel模型上創建一個構造函數,它需要和Overview對象並填充所有的屬性。像

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 
    } 
} 

東西然後你的代碼看起來像

var overView = new List<OverviewViewModel>(); 

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

+1非常好的一點!我會反對考慮這一點。但首先我喜歡讓自動映射器工作,因爲它似乎是最好的方法 –

+0

我也會認爲使用自動映射器裏面的構造函數將是很好的縮短我的代碼,而不是列出每個變量可以變長。 –

0

另一種方法是使用Linq和擴展方法如下

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... 
    } 
} 

現在,隨時隨地您的業務類是在範圍上,你有一個可發現方法的類和可以添加的類的列表一致。

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

這種更實用的方法是直觀的,流線型的,和你有某個適配器還沒有被寫入即時反饋。

從列表版本返回IEnumerable還是List是個人偏好。更廣泛的IEnumerable是更傳統的解決方案,但我傾向於從列表<>到列表<>所有的時間和下降到IEnumerable似乎是多餘的。

相關問題