2014-01-21 231 views
2

比方說,我有EF模型兩個項目可能被投射到下面的DTO:Linq to entity。嵌套投影

public class AddressDto 
{ 
    public int Id { get; set; } 
    public string Address { get; set; } 

    public static Expression<Func<Address, AddressDto>> Address2AddressDto() 
    { 
     return x => new AddressDto() { 
      Id = x.Id, 
      FullName = x.AddressLine 
     }; 
    } 
} 

public class ClientDto 
{ 
    public int Id { get; set; } 
    public int FullName { get; set; } 
    public AddressDto Address { get; set; } 
} 

我怎樣才能創建ClientDto重用從AddressDto投影到Client轉換嵌套Address投影?基本上,我想是這樣的:

public static Expression<Func<Client, ClientDto>> Client2ClientDto() 
{ 
    return x => new ClientDto() { 
     Id = x.Id, 
     FullName = x.FullName, 
     Address 
      = <Apply projection AddressDto.Address2AddressDto to object x.Address> 
    }; 
} 

我知道,我可以這樣做:

public static Expression<Func<Client, ClientDto>> Client2ClientDto() 
{ 
    return x => new ClientDto() { 
     Id = x.Id, 
     FullName = x.FullName, 
     Address = new AddressDto() { 
      Id = x.Id, 
      FullName = x.AddressLine 
     } 
    }; 
} 

但我想管理AddressDto投影在一個地方,而不是每次使用這個投影的地方(實對象要複雜得多,代碼重複會導致長期的問題)。

在我的來電顯示的代碼我想要做這樣的事情

dbRepo.Clients.Select(Client2ClientDto()) 

我所有的電流試圖結束了異常:

的LINQ表達式節點類型「調用」在LINQ不支持到實體。

回答

1

你最好打賭,如果你想遵循這種模式,可能會使用LINQKit。它會告訴你這樣做:

public static Expression<Func<Client, ClientDto>> Client2ClientDto() 
{ 
    var addr = AddressDto.Address2AddressDto() 
    return x => new ClientDto() { 
     Id = x.Id, 
     FullName = x.FullName, 
     Address = addr.Invoke(x) 
    }; 
} 

但你必須這樣稱呼它:

dbRepo.Clients.AsExpandable().Select(Client2ClientDto()) 
0

除非你已經擁有了所有預測的建成,我會考慮AutoMapper。你可以很容易地創建一個靜態映射(它會像屬性定義默認的地圖,但你可以添加其他的映射也一樣),你可以在你的靜態映射定義投影:

Mapper.CreateMap<Address, AddressDto>(); 
Mapper.CreateMap<Client, ClientDto>(); 

當AutpMapper去轉換Client對象,它會看到有一個地圖AddressAddressDto定義並將使用該。

+1

Automapper不適用於LINQ to Entities預測。 – StriplingWarrior

+0

不,但如果您先將物體水合,_then_貼圖可以起作用。 –

+1

那麼,如果我需要首先實現它,那麼我可以使用像AddressDto.Address2AddressDto()這樣的東西來實現同樣的功能。編譯()(x.Address)就是問題所在的行。我只是希望在那個時候還有一種方法還沒有實現數據。 – AlexanderM