1

僅當我使用ProjectTo時出現錯誤,我無法理解潛在問題。 (使用4.2.1.0的Automapper版本) 「LINQ to Entities不支持指定的類型成員'Tags' 僅支持初始化程序,實體成員和實體導航屬性。 我們也可以在DTO中進行這種操作,但我應該堅持只在實體一側進行操作。 讓我知道的方式或解決我可以處理這個問題,而無需升級版本。 TIA 我希望實體的Tags屬性的計算值需要映射到DTO的Tags屬性,但是當我以正常方式進行時,此功能正常工作。當在源中使用NotMapped/Computed屬性映射到目標時,Automapper ProjectTo <>()問題

源/目的地類型

public class Template : IEntity<int> 
    { 
     public string Name { get; set; } 

     public int Id { get; set; } 

     public string _Tags { get; set; } 

     [NotMapped] 
     public List<string> Tags 
     { 
      get { return _Tags == null ? null : JsonConvert.DeserializeObject<List<string>>(_Tags); } 
      set { _Tags = JsonConvert.SerializeObject(value); } 
     }  
    } 

實體配置

internal sealed class TemplateConfig : EntityTypeConfiguration<Template> 
    { 
     public TemplateConfig() 
     { 
      Ignore(x => x.Tags); 
      HasKey(x => x.Id) 
       .Map(m => 
       { 
        m.ToTable("Template"); 
        m.Property(x => x.Id).HasColumnName("ID"); 
        m.Property(x => x.Name).HasColumnName("Name"); 
        m.Property(x => x._Tags).HasColumnName("Tags"); 
       }); 
     } 
    } 

目的地DTO:

public class Template 
    { 
     public int Id { get; set; } 

     public string Name { get; set; } 

     public List<string> Tags { get; set; } 
    } 

映像配置

Mapper.CreateMap<Template, DTO.Template>();    

Mapper.CreateMap<DTO.Template, Template>(); 


//These are just for information, but getting error only when using ProjectTo. (Ignore about the OData thing) 




public virtual async Task<IQueryable<TDto>> Get(ODataQueryOptions<TDto> query) 
      { 
       try 
       { 
        var expands = query.GetExpandedPropertyNames(); 
        //Assume the collection has the data from db 
        var test = Collection.ToList(); 
        //getting the exception here 
        return await Collection.ProjectTo<TDto>(null, expands).AsTask(); 
       } 
       catch(Exception ex) 
       { 
        throw ex; 
       } 
      } 

    //Controller method 
    public override async Task<IQueryable<Template>> Get(ODataQueryOptions<Template> query) 
      { 
       try 
       { 
        List<Template> result = (await base.Get(query)).ToList(); 

        return result.AsEnumerable().AsQueryable(); 
       } 
       catch(Exception ex) 
       { 
        throw ex; 
       } 
      } 

回答

0

這是發生,因爲.ProjectTo<>(...)正在建設的select語句在SQL。由於.Tags在你的對象之間映射,它被包含在select語句中,然後實體框架抱怨它不能這樣做(因爲NotMapped屬性)。

而不是使用ProjectTo<>(...)您可以使用正常的.ToList(),然後使用.Select(Mapper.Map<TDto>)Mapper.Map<List<TDto>>(list)

這應該起作用,因爲實體框架將從字符串字段填充您的標籤字段,並且自動映射器可以執行映射。

public virtual async Task<IQueryable<TDto>> Get(ODataQueryOptions<TDto> query)  
{ 
    try 
    { 
     var expands = query.GetExpandedPropertyNames(); 

     //Assume the collection has the data from db 
     var test = Collection.ToList(); 

     var entities = expands.ToList(); 

     // you can either use .Select to project using LINQ 
     var dtos = await entities.Select(Mapper.Map<TDto>).AsTask(); 

     // or you can use Mapper.Map to a list of entities. 
     dtos = await Mapper.Map<List<TDto>>(entities).AsTask(); 

     return dtos; 
    } 
    catch(Exception ex) 
    { 
     // side note, don't throw ex, you'll lose the stack trace 
     throw; 
    } 
} 
+0

是的,使用Mapper.Map它可以工作,但是我的問題只能用於ProjectTo。我不能廢除這個實現,我需要堅持到ProjectTo只有一些調整是好的。這種情況是否完全不受Automapper支持,還是在最近的版本中修復過,或者我做錯了什麼? –

+0

不需要將邏輯複製到Map中。您可以將Map設置爲從_Tags屬性中讀取,然後在那裏反序列化它。 Automapper無法自動爲您執行此操作。 – lxalln

+0

謝謝你的回答。我通過在使用ProjectTo之前添加ToList來解決此問題,但不確定這是否是正確的修復方法。 (將它轉換爲列表,雖然會影響性能)我想在處理計算值,Json序列化或NotMapped屬性時,自動映射器沒有問題。 像這樣的工作。 'var test = Collection.ToList()。AsQueryable(); 返回等待測試。ProjectTo (null,expandeds).AsTask();' –

0

您是否嘗試過在MappingConfiguration中實現忽略?我不能完全告訴您遇到的問題的方向,但類似:

Mapper.CreateMap<Template, DTO.Template>() 
    .ForMember(dest => dest.Tags, opts => opts.Ignore()); 
+0

是的,我沒有嘗試忽略,但在這種情況下,我沒有在標籤中獲取數據。這只是一個空的列表。我只在使用ProjectTo的時候遇到問題,它可以很好地用其他方式工作,使用相同的映射配置(不使用忽略) –

相關問題