2015-04-03 38 views
0

我有這樣的代碼在LinqPad:如何重用數據映射表達式作爲編譯的表達式?

void Main() { 
    var a = Product.Select(DDL.ToDDL).Take(1).Dump(); 
} 

,成功地查詢SQL兩個表中的字段,而不是所有的人都用這個POCO類(如果內部靜態使得外部類的靜態太不知道):

public class DDL { 
    public static readonly Expression<Func<Product, DDL>> ToDDL = 
     o => new DDL { 
      id = o.identifier, 
      name = o.pbfeattext 
     }; 

    public int id {get;set;} 
    public string name {get;set;} 
} 

所以我想寫的第一行代碼是這樣的:

var a = Product.Select(o => o.AsDDL()).Take(1).Dump(); 

我試着編寫這些代碼:

public static class DDL3 { 
    public static DDL AsDDL (this Product p) { 
     return new DDL { 
      id = p.identifier, 
      name = p.pbfeattext 
     }; 
    } 
} 

哪個產生相同的結果,但它在SQL中檢索整個Product記錄而不是我們需要的兩個字段。我也試過這個代碼,但它需要做var a = Product.AsDDL().Take(1).Dump();。我需要在另一種形式(o => o.AsDDL())。 (我用構造函數甚至嘗試過,但SQL不理解這種形式的功能。)

public static class DDL3 
{ 
    public static DDL AsDDL (this Product p) 
    { 
     return new DDL { 
      id = p.identifier, 
      name = p.pbfeattext 
     }; 
    } 
} 

如何將一個代碼LINQ表達式?

+2

正確的做法與第一個例子中的做法完全相同。你知道,那個*工作正常*。 – Servy 2015-04-03 15:59:46

+0

@Servy因此沒有辦法像'(o => o.AsDDL())'那樣做?這不是要求一個實用的答案,而是問是否可能。 – 2015-04-03 16:09:52

+0

這是不可能的。 – Servy 2015-04-03 16:10:36

回答

0

這是對我工作。我如上定義表達式,然後在它下面的表達式上編譯。這是一個真正的視圖模型,將POCO映射到自身。您可以向方法添加屬性,以便JSON.NET不會序列化它們(假設...)Map和ToMap的原因是第一個用於在Entity Framework中投影字段,另一個用於在-ram集合。

public class DDL { 
    public static readonly Expression<Func<Product, DDL>> Map = 
     o => new DDL { 
      id = o.identifier, 
      name = o.pbfeattext 
     }; 
    public static readonly Func<Product, DDL> ToMap = 
     DDL.Map.Compile(); 

    public int id {get;set;} 
    public string name {get;set;} 
} 
1

AutoMapper可能適合你。看到這個:https://github.com/AutoMapper/AutoMapper/wiki/Queryable-Extensions

它需要配置一次映射,但在此之後,您可以隨時重用DTO映射。

下面是一個例子,從它:

public List<OrderLineDTO> GetLinesForOrder(int orderId) 
{ 
    Mapper.CreateMap<OrderLine, OrderLineDTO>() 
    .ForMember(dto => dto.Item, conf => conf.MapFrom(ol => ol.Item.Name); 

    using (var context = new orderEntities()) 
    { 
    return context.OrderLines.Where(ol => ol.OrderId == orderId) 
      .Project().To<OrderLineDTO>().ToList(); 
    } 
}