Проблема с созданием экземпляров из списка столбцов заключается в том, что, поскольку .NET безопасен по типу, вам понадобится тип, который вы можете создать. Когда вы используете анонимные классы (т. Е. Ключевое слово new
без имени класса), компилятор создаст для вас класс. Это анонимно, но он все еще там во время компиляции (вы можете проверить это в декомпиляторе по вашему выбору).
Если вы хотите по-настоящему быть полностью динамичным во время выполнения, вам придется динамически создавать и компилировать свои классы во время выполнения. Для этого вы можете посмотреть в пространствах имен System.CodeDom
и System.Reflection.Emit
, которые содержат классы, которые позволяют динамически создавать типы во время выполнения. Это, однако, будет довольно масштабным мероприятием, которое, по его мнению, будет стоить вашего времени. И затем вы хотите получить доступ к данным в этих объектах, поэтому вам, вероятно, придется перейти на переменные dynamic
.
Что должно быть более целесообразным, так это создать обычный класс во время компиляции и создать его в запросе LINQ. Этот класс будет содержать все возможных свойств, которые вы можете установить. Когда вы создаете экземпляр, вам не нужно заполнять все поля.
Как только у вас есть свой класс, вы можете динамически создавать выражения, которые будут его создавать. Вот для чего предназначены классы в пространстве имен System.Linq.Expressions
. Класс Expression
содержит заводские методы, которые позволяют вам создать дерево выражений, в котором вы нуждаетесь.
Чтобы создать дерево выражений, сначала нужно разложить выражение, которое вы хотите моделировать.YOR выражение для Join
будет выглядеть следующим образом (предполагается, что ваш класс контейнер с именем DataContainer
):
(t1, t2) => new DataContainer {
Value1 = t1.field1,
Value2 = t1.field2,
Value3 = t2.field3
}
Это выражение должно быть разделен на его части в соответствии с их старшинства:
- лямбда-выражения инициируется оператором лямбда
=>
: LambdaExpression
, созданный Expression.Lambda
- параметров
t1
и t2
слева от оператора лямбда: ParameterExpression
, созданный с Expression.Parameter
- Объект экземпляра
new DataContainer
справа от оператора лямбда: NewExpression
, созданный с Expression.New
- заданий внутри блока инициализации, инициированной
=
: BinaryExpression
, созданный с Expression.Assign
- свойств к слева от задания:
MemberExpression
, созданные с Expression.Property
- Свойства разыменования с
.field1
: MemberExpression
, созданным с Expression.Property
- Доступ параметр
t1
: ParameterExpression
, созданный с Expression.Parameter
(но вы повторно выражение параметра, который вы создали для лямбда-выражения)
Как вы можете видеть, это довольно утомительно по сравнению с просто писать вниз (или с помощью Dynamic LINQ). Я буду иллюстрировать это с подвыражением t1.field1
:
На этом этапе будет создан параметром t1
для левой части лямбды:
ParameterExpression t1Param = Expression.Parameter(typeof(Table1), "t1");
Что вы повторно использовать для доступа к свойству:
MemberExpression t1field1Property = Expression.Property(t1Param, "field1");
Это выражение, которое вы используете при создании своего назначения, которое вы будете использовать вместе с другими присваиваниями в выражении-экземпляре, которое вы будете использовать для правой части выражения lamdba, вдоль w с другими необходимыми выражениями. Вы также можете записать это как одно дерево (за исключением выражений параметров, которые вы собираетесь использовать повторно).
Счастливое кодирование!
Начните свое соединение в режиме просмотра db. И сопоставьте это представление с вашими сущностями. – user1681317
@ user1681317, как я уже сказал, будут случайные таблицы со случайным набором столбцов, поэтому мне нужно динамическое соединение с анонимным типом в select. Я довольно уверен, что это может быть достигнуто с помощью выражений, но мои знания в этой теме не идеальны, и я не смог реализовать это. – KorsaR
Не могли бы вы рассказать о вашем запросе. Это поможет много, если вы предоставите свой фактический запрос и скажете нам, какие части вы хотите динамизировать (это слово?). – Sefe