2016-04-14 14 views
5

Erster Beitrag hier und ganz einfach.Entity Framework Projektionsverhalten

Ich habe in der Vereinfachung einige komplexe Abfragen in einer Anwendung untersucht, die ich entwickle, und ich kratze meinen Kopf ein bisschen auf dem unten.

So sagen, ich habe diese beiden Klassen:

Eine Domain-Einheit „EmailRecipient“ (verwendet mit EF-Code-first erwartet so eine SQL-Tabelle mit den gleichen Spaltennamen erzeugt werden).

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

und eine einfache Klasse für JSON Serialisierung genannt "EmailLite" definiert als

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

In meinem Fach EF6 (.1.3) DbContext, ich habe ein DbSet EmailRecipients genannt.

So diese Linq Ausdruck gegen EmailRecipients natürlich Ausführung

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

die generierten SQL ist

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

Warum also, wenn ich tun:

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

EmailRecipients.Select(projectionFunction); 

bekomme ich die unten (komplett) SQL generiert:

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] 

Jede Hilfe würde sehr geschätzt werden!

Cheers, Sat

Antwort

3

IQueryable<T>.Select() nimmt ein Expression<Func<T,TOut>> als Parameter, die Funktion, die Sie tatsächlich ist IEnumerable<T>.Select() verwendet, die einen Delegierten nimmt. Aus diesem Grund sagen Sie EF, dass Sie ab diesem Moment IEnumerable statt IQueryable verwenden und der Rest der Abfrage im Speicher ausgeführt wird => Sie holen alle Spalten ab.

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

Alles, was Sie tun müssen, ist die Veränderung projectionFunction in einen Ausdruck und es wird funktionieren:

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

Danke - Es hatte einfach zu sein: Ich brauchte juuuuust zu schauen ein wenig näher :) wieder prost Alexander. – sat1986