dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.66k stars 3.16k forks source link

SQL Server temporal tables #4693

Closed shivajiraot closed 3 years ago

shivajiraot commented 8 years ago

Does EF Core support code first approach for Temporal tables? Looking to find a way to use Temporal tables with EF Core code first approach. Please guide me to the article if any existing already. Thank you.

rowanmiller commented 8 years ago

For the most part, the fact that a table is temporal is opaque to the data layer - so from that point of view you should be fine to connect to an existing database with temporal tables.

Here are some limitations though, that we could address in EF:

DavidBainbridgeRIT commented 8 years ago

I second this as important. Temporal tables are fantastic. They cut out a lot of boiler plate but I need that information in the front end just as easily as in the back end.

R00iBaard commented 8 years ago

Agree, I would love to be able to set this up all via EF code first.

reberinformatik commented 8 years ago

👍 See also #2229

lucasmaj commented 7 years ago

I was absolutely bummed out to find out that currently there is no obvious way to query past state using lambda expressions. Is there any way to sneak in "AS OF " into a query? (in EF6)

divega commented 7 years ago

@lucasmaj have you tried raw SQL queries as a workaround as explained above? E.g. in EF6 use SqlQuery() and FromSql() with EF Core. The latter is composable in LINQ.

lucasmaj commented 7 years ago

I haven't tried raw SQL. If EF6 had SqlQuery composable with LINQ it would do the trick for now. There is no way I would go with pure sql queries and abandon LINQ. Unless there could be a way for LINQ to pure sql back to entities in an automatic fashion.

Is there really no way to augment conversion of Expressions to SQL string so that some custom expression would translate to "AS OF" etc?

Thank you nonetheless.

sfgadjo commented 7 years ago

I look forward to full support of Temporal Tables in an upcoming release. In the meantime, I am trying to make use of the SysStartTime/SysEndTime columns added to the table in the model (using CodeFirst), and I find that EF is trying to write to those columns even when I have the model property annotated with DatabaseGenerated(DatabaseGeneratedOption.Computed). Is there a way to get around this issue so that I can at least use those columns added for versioning without writing SQL?

R00iBaard commented 7 years ago

Any update on this? It would be very nice to have this 👍

ajcvickers commented 7 years ago

@R00iBaard This issue is in the Backlog milestone. This means that it is not going to happen for the 2.0 release. We will re-assess the backlog following the 2.0 release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.

ntimmerman commented 7 years ago

+1, I would like to use this in the very near future for a new enterprise doc automation app that requires an audit history on every screen. Does anyone have any more information about the work around's for now?

pray1997 commented 7 years ago

+1

We need it too!

Or is.there any workaround, maybe something like intercepting?

ephos commented 7 years ago

+1 - I hope this gets prioritized after 2.0, this would be great to have without manual setup!

chassq commented 7 years ago

+1

kliebenberg commented 7 years ago

+1

angularDevd commented 7 years ago

+1

cSteusloff commented 7 years ago

+1

squeakyD commented 6 years ago

If you added support for interceptors (like in EF6), then it would be possible to handle inserts and updates to temporal tables by handling the generated fields.

smitpatel commented 6 years ago

@squeakyD - At present you can configure your model with generated columns to insert/update data in temporal table. Main and most useful functionality would be the query pipeline especially generating SQL with between predicate etc.

binarypatrick commented 6 years ago

+1, would love to see the ability to time slice with a lambda expression.

sifordtj commented 6 years ago

+1. Would also love to see the ability to query data with lambda ... something that gives me the FOR SYSTEM_TIME without have to use a raw SQL string.

israellot commented 6 years ago

+1

forest-devil commented 6 years ago

+1

AndriySvyryd commented 6 years ago

Please vote using the 👍 reaction on the very first post, otherwise it won't affect the order in the issue list https://github.com/aspnet/EntityFrameworkCore/issues?q=is%3Aopen+is%3Aissue+label%3Atype-enhancement+sort%3Areactions-%2B1-desc

smitpatel commented 6 years ago

Please vote using the 👍 reaction on the very first post

corrected a bit.

chassq commented 6 years ago

👍

angularDevd commented 6 years ago

:+1:

AndriySvyryd commented 6 years ago

@chassq @angularDevd Only the reactions on the first post are counted. All 👍 and +1 comments will be ignored.

ghost commented 6 years ago

Definitely +100 from me! 👍 👍 👍 👍 👍

cpoDesign commented 6 years ago

+1 here too. How about to add a base class "Temporal" entity that will add the behaviour and has the properties out of the box?

ajcvickers commented 6 years ago

See also https://github.com/aspnet/EntityFramework.Docs/issues/797-- make sure to support temporal in-memory tables.

ConX-Ryan commented 6 years ago

+1 need this in my life

MaklaCof commented 5 years ago

This issue is in the Backlog milestone. This means that it is not going to happen for the 2.0 release. We will re-assess the backlog following the 2.0 release and consider this item at that time.

EF 2.0 is done, also 2.1. Are there any new plans for this feature?

ajcvickers commented 5 years ago

@MaklaCof It's still in the backlog.

ConX-Ryan commented 5 years ago

@ajcvickers Any idea on the priority of this item? I realize each consumer of the SDK has different priorities and balancing is hard any visibility on this item would be appreciated.

ajcvickers commented 5 years ago

@ConX-Ryan I'd say it's pretty high up there relative to many things, but probably not still in the next couple of releases at least.

shivendra-aggarwal commented 5 years ago

Can we please get confirmation whether full support for Temporal tables is available with .Net EF Core 2.1 release.

Our expectations are:

Looking forward for an early response.

Thanks!

ZombieProtectionAgency commented 5 years ago

@cpoDesign A base class wouldnt be the best idea. With a base class you cant make your identity classes temporal.

I have been messing with a solution myself until this is implemented and I went the route of an "IAuditable" attribute that expects a property of type "AuditDetails" (which is Owned). Which ends up looking like this:

public class CustomUserRole : IdentityUserRole<Guid>, IAuditable
{
    public AuditDetails AuditDetails { get; set; }
}
[Owned]
public class AuditDetails
{
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime ValidFrom { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime ValidTo { get; set; }
}

That plus a custom base context that finds the attribute and fixes up the cascade behavior and replaces the MigrationSqlGenerator (plus some other logic I added to the "audit" data) and I can easily add new Temporal types.

cSteusloff commented 5 years ago

Exists any workaround? https://stackoverflow.com/questions/41514629/how-can-i-use-system-versioned-temporal-table-with-entity-framework

ajcvickers commented 5 years ago

@cSteusloff That post references EF6. This issue is about support in EF Core. That being said, there aren't any great workarounds other than what has already been discussed in this thread.

cpoDesign commented 5 years ago

There is initial nuget package here: https://www.nuget.org/packages/EFCoreTemporalSupport/ which might help :) @cSteusloff , @ajcvickers, @ZombieProtectionAgency

benhysell commented 5 years ago

@cpoDesign is the code for that Nuget hosted somewhere? I didn't see the link on the Nuget site to the GitHub repo.

weitzhandler commented 5 years ago

@cpoDesign Thanks for sharing! @ZombieProtectionAgency very nice! would love to see your MigrationSqlGenerator subclass. @benhysell It's here

ZombieProtectionAgency commented 5 years ago

@weitzhandler I was a little hesitant to show it off because it is a pretty simple rough draft and doesnt feel "good" but this was what I was using. I also use a custom DbContext that overrides ModelCreating and annotates the models/fields that are required and an annotations provider that persists the entity migrations to the model.

D-Mellenthin commented 5 years ago

There's another approach to have a package-workaround by @findulov that I just found when I searched for @cpoDesign s package: https://github.com/findulov/EntityFrameworkCore.TemporalTables Haven't tested it yet though.

sm38098 commented 5 years ago

FromSql with EF Core won't work if you've included entities that are also system versioned as 'Include' clause would only return the current state of the included entities and not the state 'as of '. So if you've navigation properties that're also system versioned, this approach won't work. The only way to get around this is by using ado .net which is pretty inapt if you're using EF Core.

IAmHopp commented 5 years ago

Would be extremely useful having this.

dvanurag1308 commented 5 years ago

Would love to see this feature in EF Core.

cgountanis commented 5 years ago

Is there any solution to db-first, temporal tables and the common error?

Cannot insert an explicit value into a GENERATED ALWAYS column Use INSERT with a column list to exclude the GENERATED ALWAYS column, or insert a DEFAULT into GENERATED ALWAYS column.

I assume it is trying to insert into the [ValidFrom] ,[ValidTo] columns, was working until convert to temporal, those are the only new columns.

chassq commented 5 years ago

You can use the DatabaseGenerated attribute. For example:

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime SysStart { get; set; }
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime SysEnd { get; set; }

Unfortunately the dotnet ef scaffold does not seem to support adding it for you at this time.