Настройка и запрос темпоральных таблиц в .Net 7C#

Место общения программистов C#
Anonymous
Настройка и запрос темпоральных таблиц в .Net 7

Сообщение Anonymous »

Используя .Net 7 Entity Framework, у меня есть система таблиц, которые помечены как временные, поэтому я могу восстановить структуру данных из прошлого (т. е. когда пользователь вносит изменения, я должен иметь возможность отменить это изменение). в предыдущее состояние). По большей части кажется, что все работает нормально, но когда я пытаюсь запросить таблицу, имеющую отношения «многие-ко-многим», именно здесь возникают проблемы.
Вот мой код:

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

 var timeConstraints = dbContext
.MyParrentDB
.TemporalAll()
.Where(c => c.Id == id)
.Select(
c => new
{
PeriodStart = EF.Property(c, "PeriodStart"),
PeriodEnd = EF.Property(c, "PeriodEnd"),
})
.Single();

var foundItem = await dbContext.MyParrentDB
.TemporalFromTo(timeConstraints.PeriodStart, timeConstraints.PeriodEnd)
.Where(c => c.Id == id)
.Include(x => x.ExampleManyToManyTable!.Where(p => p != null))
.ThenInclude(c => c.ChildTable)
.FirstOrDefaultAsync();

Но при этом возникает ошибка, что Расширение навигации поддерживается только для временной операции AsOf. Для других операций используйте соединение вручную. Итак, каков правильный способ запроса темпоральной таблицы? Вот как я настраиваю таблицы и их связи:

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

public class MyParrentDB
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public ICollection? ExampleManyToManyTable { get; set; }
}
public class ExampleManyToManyTable
{
public int MyParrentDBId { get; set; }
public MyParrentDB MyParrentDB { get; set; }
public int ChildTableId { get; set; }
public ChildTable ChildTable { get; set; }
}
public class ChildTable
{
public int Id { get; set; }
public string ChildName { get; set; } = string.Empty;
public ICollection? ExampleManyToManyTable { get; set; }
}

Setting up the table relationships:

public DbSet MyParrentDB { get; set; }
public DbSet ExampleManyToManyTable { get; set; }
public DbSet ChildTable { get; set; }

modelBuilder.Entity()
.HasKey(bc => new { bc.MyParrentDBId, bc.ChildTableId });
modelBuilder.Entity()
.HasOne(bc => bc.MyParrentDB)
.WithMany(b => b.ExampleManyToManyTable)
.HasForeignKey(bc => bc.MyParrentDBId);
modelBuilder.Entity()
.HasOne(bc => bc.ChildTable)
.WithMany(c => c.ExampleManyToManyTable)
.HasForeignKey(bc => bc.ChildTableId);

modelBuilder.Entity().Property("PeriodStart");
modelBuilder.Entity().Property("PeriodEnd");

modelBuilder.Entity().ToTable("MyParrentDB", c => c.IsTemporal());
modelBuilder.Entity().ToTable("ChildTable", c => c.IsTemporal());
modelBuilder.Entity().ToTable("ExampleManyToManyTable", c => c.IsTemporal());
РЕДАКТИРОВАТЬ:
Я изменил sql, чтобы использовать TemporalAsOf. Чтобы просмотреть добавленную строку запроса:

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

var sql = _context.MyParrentDB
.TemporalAsOf(test.PeriodStart)
.Where(c => c.Id == id)
.Include(x => x.ExampleManyToManyTable!
.Where(model => model != null))
.ThenInclude(tags => tags.ChildTable)
.ToQueryString();
Какой вывод:

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

  DECLARE @__id_0 int = 9;

SELECT
[a].[Id],
[a].[Description],
[a].[Name],
[a].[PeriodEnd],
[a].[PeriodStart],
[t].[MyParrentDBId],
[t].[ChildTableId],
[t].[PeriodEnd],
[t].[PeriodStart],
[t].[Id],
[t].[PeriodEnd0],
[t].[PeriodStart0],
[t].[ChildName]
FROM [MyParrentDB]
FOR
SYSTEM_TIME AS OF '2024-07-10T14:30:36.1001535'
AS [a] LEFT JOIN (
SELECT
[a0].[MyParrentDBId],
[a0].[ChildTableId],
[a0].[PeriodEnd],
[a0].[PeriodStart],
[a1].[Id],
[a1].[PeriodEnd] AS [PeriodEnd0],
[a1].[PeriodStart] AS [PeriodStart0],
[a1].[ChildName]
FROM
[ExampleManyToManyTable] FOR SYSTEM_TIME AS OF
'2024-07-10T14:30:36.1001535'
AS [a0] INNER JOIN [ChildTable]
FOR
SYSTEM_TIME AS OF '2024-07-10T14:30:36.1001535' AS [a1] ON
[a0].[ChildTableId] = [a1].[Id]) AS [t] ON [a].[Id] =
[t].[MyParrentDBId]
WHERE [a].[Id] = @__id_0
ORDER BY [a].[Id],
[t].[MyParrentDBId], [t].[ChildTableId]
Данные таблицы:
Изображение


Подробнее здесь: https://stackoverflow.com/questions/787 ... s-in-net-7

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