Dismissile
Dismissile

Reputation: 33071

Use an extension method for a projection in Entity Framework

Is it possible to use an extension method for a projection in Entity Framework:

public class ProjectRepository
{
    public IQueryable<ProjectDto> GetActiveProjects()
    {
        // db.Projects is a DbSet<Project>
        // i want to use a projection to convert it to ProjectDto,
        // I know I can do new ProjectDto but I would rather do an
        // extension method and abstract that logic out
        return from p in db.Projects
            where p.Status == "Active"
            select p.AsProjectDto();
    }
}

Right now I get the following error:

LINQ to Entities does not recognize the method 'AsProjectDto' method, and this method cannot be translated into a store expression.

LINQ to SQL seems to be able to handle this, but Entity Framework does not. Is there a certain way I need to write the extension method so it works in EF?

This is my extension method:

public static class ProjectExtensions
{
    public static ProjectDto AsProjectDto(this Project project)
    {
        return new ProjectDto
        {
            Id = project.Id,
            Name = project.ProjectName
        };
    }
}

Upvotes: 2

Views: 5255

Answers (1)

Joachim Isaksson
Joachim Isaksson

Reputation: 180997

To call a C# method on the data to project it, you'll need to convert to a Linq to Objects query for that part;

return (from p in db.Projects
        where p.Status == "Active"
        select p)
    .AsEnumerable().Select(x => x.AsProjectDto());

This will do the data selection from the database, and return the data as an Enumerable on which you can do the projection.

EDIT: Can't test it with EF right now, but since you asked, you should be able to use an expression to do it in the database just as well;

private static readonly Expression<Func<Project, ProjectDto>> AsProjectDto = 
    x => new ProjectDto {Id = x.Id, Name = x.ProjectName};

return db.Projects.Where(p => p.Status == "Active").Select(AsProjectDto);

Upvotes: 5

Related Questions