Похоже, что EF Core 8 должен разрешать необработанные SQL-запросы для несопоставленных типов, но я не уверен, как его использовать со сложными типами.
Например, предположим, что у вас есть следующее:
public class A
{
public int Id { get; set; }
public B B { get; set; }
// other properties
}
public class B
{
public int IdB { get; set; }
public int Description { get; set; }
}
И SQL выглядит так:
SELECT
...,
SomeColumn as IdB,
SomeDescription as Description,
...
FROM
Summary
где IdB
и Description
следует использовать для создания экземпляра B
для каждой строки.
Я пытался уйти от этого:
List<dynamic> toConvert = await _dbContext.Database.SqlQueryRaw<dynamic>(sql, parameters)
.ToListAsync( );
Что, очевидно, не работает. Есть ли способ сопоставить этот запрос с ожидаемым типом, не прибегая к командам низкого уровня и средствам чтения данных?
Спасибо.
Я даже не понимаю, почему вы ожидаете, что EF на это способен. Ему пришлось бы на лету определять сопоставление столбцов с учетом глубины. Слишком много места для неясностей и ошибок.
Интересно, есть ли что-то вроде CreateSqlQuery от NHibernate, где вы можете написать что-то вроде_session.CreateSqlQuery(sql).Future<dynamic>().ToList().Select( r => new A(..., new B(i[1) ], i[2]) А если нет, то, возможно, лучше пойти по-доброму...
Используя EF, вам всегда понадобится класс для сбора плоских данных. Тогда, конечно, вы можете проецировать во что угодно.
Нет, на данный момент это не поддерживается EF. Чтобы использовать несопоставленные типы, вам необходимо иметь плоский тип, иначе вы получите что-то вроде следующей ошибки (исходный код):
Навигация не поддерживается при использовании «SqlQuery». Либо включите этот тип в модель и используйте «FromSql» для запроса, либо игнорируйте это свойство, используя атрибут «[NotMapped]».
Внутренне EF использует довольно ограниченный набор соглашений для этого типа сопоставления, например удаление таких вещей, как принадлежащие типы и многое другое.
Параметры:
Создайте промежуточный тип, содержащий плоскую версию результата, и сопоставьте его с целевым типом.
Используйте Dapper для этого конкретного запроса, AFAIK поддерживает такой тип сопоставления.
Посмотрите на сопоставление этого типа, например, с каким-то типом объекта без ключа , возможно, в сочетании с сложным типом (правда, я немного удивлен, что они не поддерживаются в этом случае, возможно, стоило бы запросить поддержку для этого)
Не
List<B> list = await dbContext.Database.SqlQueryRaw<B>(sql, parameters).ToListAsync()
работает или нет?