Skip to content

Commit 023c55e

Browse files
committed
add support for temporal tables
1 parent de6809c commit 023c55e

File tree

4 files changed

+126
-4
lines changed

4 files changed

+126
-4
lines changed

sample/Tracker/Tracker.Core/Data/Mapping/TaskMap.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ public void Configure(Microsoft.EntityFrameworkCore.Metadata.Builders.EntityType
1818
// table
1919
builder.ToTable("Task", "dbo");
2020

21+
builder
22+
.ToTable(tableBuilder => tableBuilder
23+
.IsTemporal(temporalBuilder =>
24+
{
25+
temporalBuilder
26+
.UseHistoryTable("Task", "History");
27+
temporalBuilder
28+
.HasPeriodStart("PeriodStart")
29+
.HasColumnName("PeriodStart");
30+
temporalBuilder
31+
.HasPeriodEnd("PeriodEnd")
32+
.HasColumnName("PeriodEnd");
33+
})
34+
);
35+
2136
// key
2237
builder.HasKey(t => t.Id);
2338

src/EntityFrameworkCore.Generator.Core/Metadata/Generation/Entity.cs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Diagnostics;
1+
using System.Diagnostics;
22

33
namespace EntityFrameworkCore.Generator.Metadata.Generation;
44

@@ -162,6 +162,55 @@ public Entity()
162162
/// </value>
163163
public bool IsView { get; set; }
164164

165+
166+
/// <summary>
167+
/// Gets or sets the name of the temporal table.
168+
/// </summary>
169+
/// <value>
170+
/// The name of the temporal table.
171+
/// </value>
172+
public string TemporalTableName { get; set; }
173+
174+
/// <summary>
175+
/// Gets or sets the temporal table schema.
176+
/// </summary>
177+
/// <value>
178+
/// The temporal table schema.
179+
/// </value>
180+
public string TemporalTableSchema { get; set; }
181+
182+
/// <summary>
183+
/// Gets or sets the temporal start property.
184+
/// </summary>
185+
/// <value>
186+
/// The temporal start property.
187+
/// </value>
188+
public string TemporalStartProperty { get; set; }
189+
190+
/// <summary>
191+
/// Gets or sets the temporal start column.
192+
/// </summary>
193+
/// <value>
194+
/// The temporal start column.
195+
/// </value>
196+
public string TemporalStartColumn { get; set; }
197+
198+
/// <summary>
199+
/// Gets or sets the temporal end property.
200+
/// </summary>
201+
/// <value>
202+
/// The temporal end property.
203+
/// </value>
204+
public string TemporalEndProperty { get; set; }
205+
206+
/// <summary>
207+
/// Gets or sets the temporal end column.
208+
/// </summary>
209+
/// <value>
210+
/// The temporal end column.
211+
/// </value>
212+
public string TemporalEndColumn { get; set; }
213+
165214
void IOptionVariable.Set(VariableDictionary variableDictionary)
166215
{
167216
variableDictionary.Set(VariableConstants.TableSchema, TableSchema);
@@ -175,4 +224,4 @@ void IOptionVariable.Remove(VariableDictionary variableDictionary)
175224
variableDictionary.Remove(VariableConstants.TableName);
176225
variableDictionary.Remove(VariableConstants.EntityName);
177226
}
178-
}
227+
}

src/EntityFrameworkCore.Generator.Core/ModelGenerator.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Data;
44
using System.Linq;
@@ -14,6 +14,7 @@
1414
using Microsoft.EntityFrameworkCore.Metadata;
1515
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
1616
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata.Internal;
17+
using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal;
1718
using Microsoft.EntityFrameworkCore.Storage;
1819
using Microsoft.Extensions.Logging;
1920

@@ -146,6 +147,23 @@ private Entity CreateEntity(EntityContext entityContext, DatabaseTable tableSche
146147

147148
entity.IsView = tableSchema is DatabaseView;
148149

150+
bool? isTemporal = tableSchema[SqlServerAnnotationNames.IsTemporal] as bool?;
151+
if (isTemporal == true)
152+
{
153+
entity.TemporalTableName = tableSchema[SqlServerAnnotationNames.TemporalHistoryTableName] as string;
154+
entity.TemporalTableSchema = tableSchema[SqlServerAnnotationNames.TemporalHistoryTableSchema] as string;
155+
156+
entity.TemporalStartProperty = tableSchema[SqlServerAnnotationNames.TemporalPeriodStartPropertyName] as string;
157+
158+
entity.TemporalStartColumn = tableSchema[SqlServerAnnotationNames.TemporalPeriodStartColumnName] as string
159+
?? entity.TemporalStartProperty;
160+
161+
entity.TemporalEndProperty = tableSchema[SqlServerAnnotationNames.TemporalPeriodEndPropertyName] as string;
162+
163+
entity.TemporalEndColumn = tableSchema[SqlServerAnnotationNames.TemporalPeriodEndColumnName] as string
164+
?? entity.TemporalEndProperty;
165+
}
166+
149167
entityContext.Entities.Add(entity);
150168

151169
return entity;
@@ -679,4 +697,4 @@ private static bool IsIgnored(string name, IEnumerable<MatchOptions> excludeExpr
679697
return false;
680698
}
681699

682-
}
700+
}

src/EntityFrameworkCore.Generator.Core/Templates/MappingClassTemplate.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,5 +363,45 @@ private void GenerateTableMapping()
363363
: $"builder.{method}(\"{_entity.TableName}\");");
364364

365365
CodeBuilder.AppendLine();
366+
367+
if (_entity.TemporalTableName.IsNullOrEmpty())
368+
return;
369+
370+
CodeBuilder.AppendLine("builder");
371+
CodeBuilder.IncrementIndent();
372+
CodeBuilder.AppendLine(".ToTable(tableBuilder => tableBuilder");
373+
CodeBuilder.IncrementIndent();
374+
CodeBuilder.AppendLine(".IsTemporal(temporalBuilder =>");
375+
CodeBuilder.AppendLine("{");
376+
CodeBuilder.IncrementIndent();
377+
CodeBuilder.AppendLine("temporalBuilder");
378+
CodeBuilder.IncrementIndent();
379+
380+
CodeBuilder.AppendLine(_entity.TemporalTableSchema.HasValue()
381+
? $".UseHistoryTable(\"{_entity.TemporalTableName}\", \"{_entity.TemporalTableSchema}\");"
382+
: $".UseHistoryTable(\"{_entity.TemporalTableName}\");");
383+
384+
CodeBuilder.DecrementIndent();
385+
CodeBuilder.AppendLine("temporalBuilder");
386+
CodeBuilder.IncrementIndent();
387+
CodeBuilder.AppendLine($".HasPeriodStart(\"{_entity.TemporalStartProperty}\")");
388+
CodeBuilder.AppendLine($".HasColumnName(\"{_entity.TemporalStartColumn}\");");
389+
390+
CodeBuilder.DecrementIndent();
391+
CodeBuilder.AppendLine("temporalBuilder");
392+
CodeBuilder.IncrementIndent();
393+
CodeBuilder.AppendLine($".HasPeriodEnd(\"{_entity.TemporalEndProperty}\")");
394+
CodeBuilder.AppendLine($".HasColumnName(\"{_entity.TemporalEndColumn}\");");
395+
396+
CodeBuilder.DecrementIndent();
397+
CodeBuilder.DecrementIndent();
398+
CodeBuilder.AppendLine("})");
399+
400+
CodeBuilder.DecrementIndent();
401+
CodeBuilder.AppendLine(");");
402+
403+
CodeBuilder.DecrementIndent();
404+
405+
CodeBuilder.AppendLine();
366406
}
367407
}

0 commit comments

Comments
 (0)