Entity Framework 投影行为

5

这是我在这里发布的第一篇文章,内容相对简单。

我一直在研究如何简化我正在开发的应用程序中的一些复杂查询,但以下内容让我有些困惑。

假设我有以下两个类:

一个领域实体“EmailRecipient”(与EF Code First一起使用,因此预计将生成具有相同列名称的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; }
}

定义一个简单的用于JSON序列化的类"EmailLite"

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

在我的专用 EF6(.1.3) DbContext 中,我有一个名为 EmailRecipients 的 DbSet。
因此,自然而然地对 EmailRecipients 执行此 linq 表达式。
EmailRecipients.Select(x => new EmailLite
        {
            Id = x.Id,
            EmailAddress = x.EmailAddress,
            FriendlyName = x.FriendlyName
        });

生成的SQL语句为:
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]

非常感谢您的帮助!

谢谢, Sat

1个回答

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
};

谢谢 - 它必须是简单的:我只需要再仔细看一点点 :) 再次感谢 Alexander。 - sat1986

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接