2016-04-14 96 views
5

这里的第一篇文章很简单。实体框架投影行为

我一直在寻找简化在我正在开发的应用程序中的一些复杂的查询,我在我的头上挠了一下。

所以说我有以下两类:

域实体“EmailRecipient”(使用EF代码优先使用,因此希望用相同的列名生成SQL表)。

public class EmailRecipient 
{ 
    public Guid Id { get; set; } 
    public string FriendlyName { get; set; } 
    public string ExchangeName { get; set; } 
    public string Surname { get; set; } 
    public string Forename { get; set; } 
    public string EmailAddress { get; set; } 
    public string JobTitle { get; set; } 

    public virtual List<SentEmail> SentEmails { get; set; } 
} 

,并定义为所谓的 “EmailLite” JSON序列化一个简单的类作为

public class EmailLite 
{ 
    public string EmailAddress { get; set; } 
    public Guid Id { get; set; } 
    public string FriendlyName { get; set; } 
} 

在我的专业EF6(1.3)的DbContext,我有一个名为DbSet EmailRecipients。

所以很自然的执行对EmailRecipients

EmailRecipients.Select(x => new EmailLite 
     { 
      Id = x.Id, 
      EmailAddress = x.EmailAddress, 
      FriendlyName = x.FriendlyName 
     }); 

生成的SQL这个LINQ表达式是

SELECT 
    1 AS [C1], 
    [Extent1].[Id] AS [Id], 
    [Extent1].[EmailAddress] AS [EmailAddress], 
    [Extent1].[FriendlyName] AS [FriendlyName] 
    FROM [dbo].[EmailRecipients] AS [Extent1] 

那么,为什么当我这样做:

Func<EmailRecipient, EmailLite> projectionFunction = x => new EmailLite 
     { 
      Id = x.Id, 
      EmailAddress = x.EmailAddress, 
      FriendlyName = x.FriendlyName 
     }; 

EmailRecipients.Select(projectionFunction); 

我会得到以下(完整)生成的SQL:

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[FriendlyName] AS [FriendlyName], 
    [Extent1].[ExchangeName] AS [ExchangeName], 
    [Extent1].[Surname] AS [Surname], 
    [Extent1].[Forename] AS [Forename], 
    [Extent1].[EmailAddress] AS [EmailAddress], 
    [Extent1].[JobTitle] AS [JobTitle], 
    [Extent1].[SubscribedOn] AS [SubscribedOn] 
    FROM [dbo].[EmailRecipients] AS [Extent1] 

任何帮助将不胜感激!

干杯, 周六

回答

3

IQueryable<T>.Select()需要一个Expression<Func<T,TOut>>作为参数,你其实用功能是IEnumerable<T>.Select()这需要一个委托。因此,您告诉EF,从那一刻起,您正在使用IEnumerable而不是IQueryable,其余查询将在内存中执行=>您正在获取所有列。

EmailRecipients <-- in memory from here on --> .Select(projectionFunction); 

所有你需要做的是改变projectionFunction到表达,也将努力:

Expression<Func<EmailRecipient, EmailLite>> projectionFunction = x => new EmailLite 
{ 
    Id = x.Id, 
    EmailAddress = x.EmailAddress, 
    FriendlyName = x.FriendlyName 
}; 
+0

谢谢你 - 它必须是简单的:我需要juuuuust再看仔细一点:)干杯亚历山大。 – sat1986