I can use temporal tables in SQL Server 2016. Entity Framework 6 unfortunately does not know this feature yet. Is there the possibility of a workaround to use the new querying options (see msdn) with Entity Framework 6?
I created a simple demo project with an employee temporal table:
I used the edmx to map the table to entity (thanks to Matt Ruwe):
Everything works fine with pure sql statements:
using (var context = new TemporalEntities())
{
var employee = context.Employees.Single(e => e.EmployeeID == 2);
var query =
$@"SELECT * FROM [TemporalTest].[dbo].[{nameof(Employee)}]
FOR SYSTEM_TIME BETWEEN
'0001-01-01 00:00:00.00' AND '{employee.ValidTo:O}'
WHERE EmployeeID = 2";
var historyOfEmployee = context.Employees.SqlQuery(query).ToList();
}
Is it possible to add the history functionality to every entity without pure SQL? My solution as entity extension with reflection to manipulate the SQL query from IQuerable
isn't perfect.
Is there an existing extension or library to do this?
edit: (Based on the commentary by Pawel)
I tried to use a Table-valued Function:
CREATE FUNCTION dbo.GetEmployeeHistory(
@EmployeeID int,
@startTime datetime2,
@endTime datetime2)
RETURNS TABLE
AS
RETURN
(
SELECT
EmployeeID,
[Name],
Position,
Department,
[Address],
ValidFrom,
ValidTo
FROM dbo.Employee
FOR SYSTEM_TIME BETWEEN @startTime AND @endTime
WHERE EmployeeID = @EmployeeID
);
using (var context = new TemporalEntities())
{
var employee = context.Employees.Single(e => e.EmployeeID == 2);
var historyOfEmployee =
context.GetEmployeeHistory(2, DateTime.MinValue, employee.ValidTo).ToList();
}
Do I have to create a function for each entity or is there a generic option?
Initial support for Temporal Tables has been added here: e7c0b9d (model/metadata part) and here 4b25a88 (query part) and will be available in the next preview (Preview 8), as well as in current nightly bits.
Usage:
Mapping entity to a temporal table can be done in the OnModelCreating, like this:
additional configuration is also supported - history table name/schema, names for period start and period end columns
Migrations are supported so existing entities can be converted to temporal.
Querying:
Supported operations:
TemporalAsOf
,TemporalAll
,TemporalBetween
,TemporalFromTo
,TemporalContainedIn
.Some limitations and considerations
Queries that use temporal operations are always marked as ``NoTracking`. Multiple entities with the same key could be returned from such queries and EF would not be able to resolve their identities properly otherwise.
Temporal operations are supported directly on
DbSet
, rather thanIQueryable
. In case of inheritance, they can't be applied onOfType
operation. Instead, use:Navigation expansion is only supported for
AsOf
operation, since it's the only temporal operation that guarantees consistency of the result graph. For other temporal operations navigations must be created manually usingJoin
.When expanding navigation, the target entity must also be mapped to temporal table. Temporal operation gets propagated from source to the target. Navigating from temporal to non-temporal entity is not supported.
will return customers and their orders as of Jan 1st 2020. Temporal operation gets applied to customers AND orders automatically.
Quote from maumar