Projecting an Entity Framework

The first post is pretty simple here.

I am studying the simplification of some complex queries in the application that I am developing and scratching my head a bit below.

So to speak, I have these two classes:

Domain object "EmailRecipient" (used with the first EF code, so expect the SQL table to be generated with the same column names).

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

and a simple JSON serialization class called "EmailLite" defined as

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

In my specialized Eb6 (.1.3) DbContext, I have a DbSet called EmailRecipients.

So, naturally executing this linq expression against EmailRecipients

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

generated SQL

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

So why when I do:

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

I get the following (full) SQL code:

 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] 

Any help would be appreciated!

Cheers, Sat

+5
source share
1 answer

IQueryable<T>.Select() takes an Expression<Func<T,TOut>> as parameter, the function you are actually using is IEnumerable<T>.Select() , which the delegate takes. Because of this, you tell EF that from now on you are using IEnumerable , not IQueryable , and the rest of the query will be executed in memory => you retrieve all the columns.

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

All you have to do is change the projectionFunction into an expression and it will work:

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

Source: https://habr.com/ru/post/1247157/


All Articles