Проблема с иерархией и отношениями TPC в EF Core 8 + PostgreSQLC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Проблема с иерархией и отношениями TPC в EF Core 8 + PostgreSQL

Сообщение Anonymous »

У меня возникла проблема при попытке использовать сопоставление иерархии TPC в EF Core 8, где я получаю InvalidCastExceptions.
Я хотел иметь BaseAuditedEntity< /code> для большинства моделей в моем приложении (только за исключением моделей Identity), чтобы я мог использовать его для несвязанной функции: объекта TierList, который имеет множество TierListItem и каждый TierListItem относится к сущности BaseAuditedEntity в приложении, например Circle (музыкальная группа) или ArrangementSong.
(Упрощенные) модели :

Код: Выделить всё

public class Circle : BaseAuditedEntity
{
public string Name { get; set; }

public List ArrangementSongs { get; set; }
}

public class ArrangementSong : BaseAuditedEntity
{
public string Title { get; set; }

public int CircleId { get; set; }
public Circle Circle { get; set; }

public List OfficialSongs { get; set; }
public List OfficialSongArrangementSongs { get; set; }
}

public class OfficialSong : BaseAuditedEntity
{
public string Title { get; set; }

public required List ArrangementSongs { get; set; }
public required List OfficialSongArrangementSongs { get; set; }
}

public class TierListItem : BaseEntity
{
public int TierListTierId { get; set; }
public TierListTier TierListTier { get; set; } = default!;

public int SourceId { get; set; }
public BaseAuditedEntity Source { get; set; }
}

public abstract class BaseAuditedEntity : BaseEntity
{
public DateTime CreatedOn { get; set; }
public string CreatedByUserName { get; set; } = string.Empty;

public DateTime? UpdatedOn { get; set; }
public string? UpdatedByUserName { get; set; }
}

public abstract class BaseEntity
{
public int Id { get; set; }
}
Конфигурация базовых классов:

Код: Выделить всё

        modelBuilder.Entity()
.UseTpcMappingStrategy();

modelBuilder.Entity()
.HasMany(c => c.ArrangementSongs)
.WithOne(a => a.Circle)
.IsRequired();
Простой запрос может быть таким:

Код: Выделить всё

var arrangementSongs_Res = await _context.ArrangementSongs
.Include(a => a.Circle)
.Include(a => a.OfficialSongs)
.Select(a => new ArrangementSongResponse(a)
{
CircleName = a.Circle.Name,
OfficialSongTitles = a.OfficialSongs.Select(os =>  os.Title).ToList(),
})
.ToListAsync();
Но при запуске я получаю это исключение (его не произойдет, если я удалю строку .Include(a => a.Circle)):

Код: Выделить всё

[16:13:14 INFOR] Executed DbCommand (25ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT a.id, a.created_by_user_name, a.created_on, a.updated_by_user_name, a.updated_on, a.circle_id, a.status, a.title, a.title_japanese, a.title_romaji, a.url, c.id, c.created_by_user_name, c.created_on, c.updated_by_user_name, c.updated_on, c.name, c.status, t.id, t.arrangement_song_id, t.official_song_id, t.id0, t.created_by_user_name, t.created_on, t.updated_by_user_name, t.updated_on, t.context, t.game_id, t.title, t0.title, t0.id, t0.id0
FROM arrangement_songs AS a
INNER JOIN circles AS c ON a.circle_id = c.id
LEFT JOIN (
SELECT o.id, o.arrangement_song_id, o.official_song_id, o0.id AS id0, o0.created_by_user_name, o0.created_on, o0.updated_by_user_name, o0.updated_on, o0.context, o0.game_id, o0.title
FROM official_song_arrangement_song AS o
INNER JOIN official_songs AS o0 ON o.official_song_id = o0.id
) AS t ON a.id = t.arrangement_song_id
LEFT JOIN (
SELECT o2.title, o1.id, o2.id AS id0, o1.arrangement_song_id
FROM official_song_arrangement_song AS o1
INNER JOIN official_songs AS o2 ON o1.official_song_id = o2.id
) AS t0 ON a.id = t0.arrangement_song_id
ORDER BY a.id, c.id, t.id, t.id0, t0.id
[16:13:14 ERROR] An exception occurred while iterating over the results of a query for context type 'Touhou_Songs.Data.AppDbContext'.
System.InvalidCastException: Unable to cast object of type 'Touhou_Songs.App.Unofficial.Songs.ArrangementSong' to type 'Touhou_Songs.App.Unofficial.Circles.Circle'.
at lambda_method70(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
System.InvalidCastException: Unable to cast object of type 'Touhou_Songs.App.Unofficial.Songs.ArrangementSong' to type 'Touhou_Songs.App.Unofficial.Circles.Circle'.
at lambda_method70(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
[16:13:14 INFOR] Executed action Touhou_Songs.App.Unofficial.ArrangementSongs.ArrangementSongsController.GetArrangementSongs (Touhou_Songs) in 2101.1069ms
[16:13:14 INFOR] Executed endpoint 'Touhou_Songs.App.Unofficial.ArrangementSongs.ArrangementSongsController.GetArrangementSongs (Touhou_Songs)'
[16:13:15 ERROR] HTTP GET /api/ArrangementSongs responded 500 in 2264.5217 ms
System.InvalidCastException: Unable to cast object of type 'Touhou_Songs.App.Unofficial.Songs.ArrangementSong' to type 'Touhou_Songs.App.Unofficial.Circles.Circle'.
at lambda_method70(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Touhou_Songs.App.Unofficial.ArrangementSongs.Features.GetArrangementSongsHandler.Handle(GetArrangementSongsQuery request, CancellationToken cancellationToken) in D:\Dev\SSD Projects\Main\Touhou_Songs\API\Server\App\Unofficial\ArrangementSongs\Features\GetArrangementSongs.cs:line 41
at Touhou_Songs.App.Unofficial.ArrangementSongs.ArrangementSongsController.GetArrangementSongs(GetArrangementSongsQuery query) in D:\Dev\SSD Projects\Main\Touhou_Songs\API\Server\App\Unofficial\ArrangementSongs\ArrangementSongsController.cs:line 19
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope&  scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)
[16:13:15 ERROR] An unhandled exception has occurred while executing the request.
System.InvalidCastException: Unable to cast object of type 'Touhou_Songs.App.Unofficial.Songs.ArrangementSong' to type 'Touhou_Songs.App.Unofficial.Circles.Circle'.
at lambda_method70(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Touhou_Songs.App.Unofficial.ArrangementSongs.Features.GetArrangementSongsHandler.Handle(GetArrangementSongsQuery request, CancellationToken cancellationToken) in D:\Dev\SSD Projects\Main\Touhou_Songs\API\Server\App\Unofficial\ArrangementSongs\Features\GetArrangementSongs.cs:line 41
at Touhou_Songs.App.Unofficial.ArrangementSongs.ArrangementSongsController.GetArrangementSongs(GetArrangementSongsQuery query) in D:\Dev\SSD Projects\Main\Touhou_Songs\API\Server\App\Unofficial\ArrangementSongs\ArrangementSongsController.cs:line 19
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean&  isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
[16:13:15 INFOR] Request finished HTTP/2 GET https://localhost:5000/api/ArrangementSongs - 500 null text/plain; charset=utf-8 2424.9688ms
Я предполагаю, что это проблема со строками BaseEntity в БД. Таблицы BaseEntity нет, потому что это TPC, но после миграции я обновил модели с автономных идентификаторов до использования базового класса, и тогда я вижу, что они используют общую последовательность. Однако существующие идентификаторы не изменились, поэтому существует множество строк с одинаковыми идентификаторами. Но я не уверен, является ли это причиной или как это исправить.
Любая помощь в решении этой моей проблемы будет очень признательна!

Подробнее здесь: https://stackoverflow.com/questions/786 ... postgresql
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»