Использование метода ModelBuilder Query с унаследованными классами (EF core 2.1) - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть некоторые проблемы с использованием метода Query dbContext в базовом классе, который обеспечивает некоторое наследование одного другого класса (только для свойств наследования, а не для построения модели / базы данных)

В моих службах репо я называю что-то вроде:

IEnumerable<CoasterExtended> coasters = await _db.Query<CoasterExtended>()
            .FromSql(GetCoastersProcedure, pageNumberParam, pageSizeParam, orderByParam, sortParam, breweryIdParam, searchParam, coasterTypeParam)
            .ToListAsync();

GetCoastersProcedure - это процедура sql, которая возвращает все свойства класса CoasterExtended.Этот класс не используется для моделирования / построения базы данных.Это просто зеркало результата процедуры sql.

В моем методе OnModelCreating у меня просто есть:

builder.Query<CoasterExtended>();

Запрос результата процедуры sql работал нормально, пока я не решил использовать этот класс для наследования:

public class CollectionItemExtended : CoasterExtended {
    // some additional properties
}

И метод OnModelCreating:

builder.Query<CollectionItemExtended>();

Запрос (типа CoasterExtended) теперь возвращает ошибку «Обязательный столбец« Дискриминатор »не присутствовал в результатах операции« FromSql »».Я знаю, что дискриминатор используется для унаследованных типов, но я использую оба класса для отражения результатов отдельных процедур SQL (эти результаты я просто сопоставляю с желаемыми классами модели приложения)

Поэтому я не хочу выбирать (и подделывать) дискриминатор ... Я просто хочу отобразить результаты процедур SQL для независимых классов (которые я унаследовал только потому, что я не хочу дублировать свойства и средства отображения, которые следуют).Как я могу добиться, чтобы результат запроса игнорировал наследование и просто возвращал описанные типы?

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Проблема состоит в том, что и базовый, и производные классы зарегистрированы как типы запросов , поэтому EF Core считает, что они реализуют стратегию наследования базы данных TPH (аналогично обычным типам сущностей).

Если вы хотите просто использовать общие свойства, используйте базовый класс, который не зарегистрирован как сущность или тип запроса.

В вашем случае измените имя класса CoasterExtended, чтобы сказать CoasterExtendedBase, иCoasterExtended и CollectionItemExtended наследуются от него:

public class CoasterExtended : CoasterExtendedBase { }

public class CollectionItemExtended : CoasterExtendedBase
{
    // some additional properties
}

Теперь вы можете зарегистрировать как CoasterExtended, так и CollectionItemExtended как типы запросов, и все будет работать так, как ожидается.

0 голосов
/ 11 февраля 2019

Query на самом деле здесь лишнее.Это сводится к логике FromSQL.Другими словами, Query<Foo>.FromSQL на самом деле просто FromSQL<Foo>.Короче говоря, FromSQL может работать только с типами сущностей, то есть с типами, которые фактически сопоставлены с вашей базой данных.Вот почему предполагается реляционное наследование со столбцом Discriminator.Другими словами, он не предназначен для отображения на случайные типы объектов C #.

EDIT

Хотя вышеприведенное верно, оно не является исчерпывающим.Лучше сказать, что DbSet<T>.FromSQL должен быть типом сущности.В EF Core 2.1 добавлена ​​поддержка «наборов запросов», но вы должны определить такой набор запросов в своем контексте, чтобы использовать его:

public DbQuery<CollectionItemExtended> CollectionItemExtendeds { get; set; }

Затем вы можете использовать FromSQL для этого:

_context.CollectionItemExtendeds.FromSQL(...);
...