Это интригующий вопрос.Я думаю, что DTO может помочь вам в этом, но есть ограничения и подводные камни, на которые стоит обратить внимание.Возьмите следующий LINQPad Пример:
class ProjectDTO
{
public string Name { get; set; }
public static Expression<Func<Project, ProjectDTO>> 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:
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]
Как видите, вы не можете использовать конструктор копирования для назначения свойствDTO, поскольку это заставляет весь объект извлекаться из базы данных.
Это также немного ограничивает, если вы хотите расширить базовый DTO и добавить больше свойств для более специализированных представлений данных, что означает, что вы могли быВ итоге получим несколько Expression с похожим кодом.
Однако мне очень нравится второй вариант, но я уверен, что этот вариант весьма ограничен проекциями одного типа, рассмотрим следующий пример:
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
Я не думаю, что вы можете использовать выражение в этом типе синтаксиса запроса.Вообще говоря, я не думаю, что будет решение, которое будет работать по всем направлениям.Возможно, вам придется пересмотреть свой дизайн, чтобы увидеть, можете ли вы предоставить меньше прогнозов, основываясь на том, что некоторые свойства очень дешевы, чтобы всегда включать их в запрос?
Без использования библиотеки Dynamic LINQ или построения дерева выражений вручнуюЯ также хотел бы узнать, возможно ли с помощью LINQ-SQL / LINQ-Entities создавать динамические выборки.