Pass in an Expression to linq's Select

前端 未结 4 1764
甜味超标
甜味超标 2021-02-13 02:07

This is linq-to-sql

I have a lot of different classes all doing the same query, but projecting the results slightly differently. Ideally I\'d like to b

4条回答
  •  粉色の甜心
    2021-02-13 02:54

    This is an intriguing question. I think a DTO can help you out here, but there are limitations and pitfalls to watch out for. Take the following LINQPad Example:

    class ProjectDTO
    {
        public string Name { get; set; }
    
        public static Expression> ToDTO = (e) => new ProjectDTO
        {
            Name = e.Name
        };
    
        public ProjectDTO() {}
    
        public ProjectDTO(Project project)
        {
            Name = project.Name;
        }
    }
    
    void Main()
    {
        Projects.Select(p => p.Name).Dump();
        Projects.Select(ProjectDTO.ToDTO).Dump();
        Projects.Select(p => new ProjectDTO(p)).Dump();
    }
    

    SQL Generated:

    SELECT [t0].[Name]
    FROM [Project] AS [t0]
    GO
    
    SELECT [t0].[Name]
    FROM [Project] AS [t0]
    GO
    
    SELECT [t0].[ProjectId], [t0].[Name], [t0].[Description], [t0].[DateCreated], [t0].[DateModified], [t0].[DateComplete], [t0].[CreatedBy]
    FROM [Project] AS [t0]
    

    As you can see, you cannot use a copy-constructor to assign the properties of the DTO as this forces the entire object to be pulled back from the database.

    This also slightly limiting if you wanted to extend the base DTO and add more properties for more specialised views of the data, which means you could end up with multiple Expression's with similar code.

    However, I quite like option two, but i'm sure this option is quite likely restricted to single type projections, consider the following example:

    var query = from p in Projects
                join t in Tasks on p.ProjectId equals t.ProjectId
                select ProjectDTO.ToDTO; //Can't be used like this
    

    I don't think you can use the Expression in this type of query-syntax. Generally speaking, I don't think there will be a solution that works across the board. You may have to review your design to see if you can provide less projections, based on some of the properties being very cheap to always include in the query?

    Without using the Dynamic LINQ library or building the expression tree manually, I would also like to see if it is possible with LINQ-SQL/LINQ-Entities to create dynamic selects.

提交回复
热议问题