簡體   English   中英

地圖ICollection <Model> 列出 <ViewModel> 使用AutoMapper

[英]Map ICollection<Model> to List<ViewModel> using AutoMapper

我正在嘗試在代碼中使用AutoMapper。 映射集合時,出現此錯誤

LINQ to Entities無法識別方法“ System.Collections.Generic.List 1[Web.ViewModels.FirmMatterViewModel] Map[ICollection 1,List 1](System.Collections.Generic.ICollection 1 [Web.Models.FirmMatter])”方法,並且該方法不能轉換為商店表達式。

這是我如何執行映射的代碼:

var clientMatters = 
    from cm in db.ClientMatters
        .Include(t => t.Billing)
        .Include(t => t.Billing.Office)
        .Include(t => t.Billing.Client)
        .Include(t => t.FirmMatters)
    select new ClientMatterIndexListViewModel
    {
        ClientMatterID = cm.ClientMatterID,
        BillingID = cm.BillingID,
        OfficeName = cm.Billing.Office.Name,
        ClientName = cm.Billing.Client.Name,
        ClientMatterNo = cm.ClientMatterNo,
        Description = cm.Description,
        FirmMatters = Mapper.Map<ICollection<FirmMatter>, List<FirmMatterViewModel>>(cm.FirmMatters)
    };

我已經為FirmMatter創建了地圖

Mapper.CreateMap<FirmMatter, FirmMatterViewModel>();

我的代碼有什么問題?

我知道您接受了答案,但是我要么不會使用AutoMapper來執行此操作,要么不會一直使用AutoMapper來執行。

Include s和AsEnumerable()的組合效率很低,因為SQL語句將選擇所有表的所有列並將此膨脹的結果集拉入內存。 最后,您只需要數量非常有限的屬性。 為什么不尋找一種只選擇所需數據的方法呢?

沒有AutoMapper

沒有AsEnumerable()和AM且具有內聯投影的查詢效率更高:

var clientMatters = 
    from cm in db.ClientMatters
    select new ClientMatterIndexListViewModel
    {
        ClientMatterID = cm.ClientMatterID,
        BillingID = cm.BillingID,
        OfficeName = cm.Billing.Office.Name,
        ClientName = cm.Billing.Client.Name,
        ClientMatterNo = cm.ClientMatterNo,
        Description = cm.Description,
        FirmMatters = cm.FirmMatters.Select(fm => new FirmMatterViewModel { ... } }
    };

您不需要在此處包含,因為查詢不會返回可在其中包含集合和引用的ClientMatter對象。 select使用這些導航屬性足以使EF生成所有必需的聯接。

使用AutoMapper

如果您還定義了ClientMatterClientMatterIndexListViewModel之間的映射,則可以使用AutoMapper的Project.To方法獲得與上一個查詢相同的效果:

using AutoMapper.QueryableExtensions;
...

var clientMatters = db.ClientMatters
                      .Project().To<ClientMatterIndexListViewModel>();

為此, ClientMatterIndexListViewModel應該包含如下屬性:

public IEnumerable<FirmMatterViewModel> FirmMatters { get; set; }

LINQ to Entities嘗試將Map方法轉換為SQL,這顯然是無法撤消的。 為避免該錯誤,應在調用map之前將查詢轉換為可枚舉:

var query = 
    from cm in db.ClientMatters
        .Include(t => t.Billing)
        .Include(t => t.Billing.Office)
        .Include(t => t.Billing.Client)
        .Include(t => t.FirmMatters)
    select cm;

var clientMatters = query.AsEnumerable().Select(cm => new ClientMatterIndexListViewModel
{
    ClientMatterID = cm.ClientMatterID,
    BillingID = cm.BillingID,
    OfficeName = cm.Billing.Office.Name,
    ClientName = cm.Billing.Client.Name,
    ClientMatterNo = cm.ClientMatterNo,
    Description = cm.Description,
    FirmMatters = Mapper.Map<ICollection<FirmMatter>, List<FirmMatterViewModel>>(cm.FirmMatters)
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM