Net Core:实体框架和 SQL Server 时态表、自动脚手架
Posted
技术标签:
【中文标题】Net Core:实体框架和 SQL Server 时态表、自动脚手架【英文标题】:Net Core: Entity Framework and SQL Server Temporal Tables, Automatic Scaffolding 【发布时间】:2020-10-04 07:46:54 【问题描述】:我们在使用带有 SQL Server 临时 SystemVersioningTables 的 Entity Framework Core 2.2 时遇到问题。
以下解决了 Entity Framework 和系统版本控制列的问题。 entityframework core and sql 2016 temporal tables
使用该解决方案,Entity Framework Core 2.2 是否有办法在 SystemVersioning 列上自动添加 DatabaseGeneratedOption.Computed
或 OnModelCreating
?
dotnet ef dbcontext scaffold
中有命令参数吗?
我们正在寻找一种在自动数据库脚手架期间自动添加此功能的方法。这样一来,我们就不必为所有 1000 多个表手动添加它,或者在我们添加新表的任何时候添加。
公司有很多数据库。
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
或
public partial class DatabaseDBContext : DbContext
partial void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity<Table1>(entity =>
entity.Property(e => e.StartTime)
.ValueGeneratedOnAddOrUpdate();
entity.Property(e => e.EndTime)
.ValueGeneratedOnAddOrUpdate();
);
我们使用的是 .NET Core 2.2。
注意:我们不想隐藏 SQL Server 列,作为文章中的第三个解决方案。
【问题讨论】:
【参考方案1】:在 OnModelCreating 中,您可以检查和修改模型。所以这很简单:
protected override void OnModelCreating(ModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
foreach (var et in modelBuilder.Model.GetEntityTypes())
foreach (var prop in et.GetProperties())
if (prop.Name == "StartTime"|| prop.Name == "EndTime")
prop.ValueGenerated = Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.OnAddOrUpdate;
这适用于 EF Core 3.1。 EF Core 2.2 不受支持。 2.1 是 LTS 分支,3.1 也是。见https://devblogs.microsoft.com/dotnet/net-core-2-2-will-reach-end-of-life-on-december-23-2019/
【讨论】:
太好了,可惜我用的是EF 2.2,你说2.1是LTS分支?你认为他们最终会通过 LTS 将该功能带到 2.2 吗? 2.2 没有修复或增强功能。你可以在 2.2 中做同样的事情。语法可能有点不同。 嗨大卫,也许你可以回答这个问题? ***.com/questions/62445608/… @david-browne-microsoft 为什么是ValueGenerated.OnAddOrUpdate
而不是 ValueGenerated.OnAdd
?还是两者都做同样的事情?【参考方案2】:
.NET 6 和 Entity Framework Core 6.0 支持开箱即用的 SQL Server 时态表。
用法:
public class Customer
public Guid Id get; set;
public string Name get; set;
public List<Order> Orders get; set;
public class Order
public Guid Id get; set;
public DateTime OrderDate get; set;
public Product Product get; set;
public Customer Customer get; set;
public class Product
public Guid Id get; set;
public string Name get; set;
public decimal Price get; set;
使用 IsTemporal:
protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder
.Entity<Customer>()
.ToTable("Customers", b => b.IsTemporal());
modelBuilder
.Entity<Product>()
.ToTable("Products", b => b.IsTemporal());
modelBuilder
.Entity<Order>()
.ToTable("Orders", b => b.IsTemporal());
查询历史数据:
var productSnapshots = context.Products
.TemporalBetween(from, to)
.OrderBy(product => EF.Property<DateTime>(product, "PeriodStart"))
.Where(product => product.Name == productName)
.Select(product =>
new
Product = product,
PeriodStart = EF.Property<DateTime>(product, "PeriodStart"),
PeriodEnd = EF.Property<DateTime>(product, "PeriodEnd")
)
.ToList();
查找特定的历史记录
var order = context.Orders
.TemporalAsOf(on)
.Include(e => e.Product)
.Include(e => e.Customer)
.Single(order =>
order.Customer.Name == customerName
&& order.OrderDate > on.Date
&& order.OrderDate < on.Date.AddDays(1));
恢复已删除的数据
var customerDeletedOn = context.Customers
.TemporalAll()
.Where(customer => customer.Name == customerName)
.OrderBy(customer => EF.Property<DateTime>(customer, "PeriodEnd"))
.Select(customer => EF.Property<DateTime>(customer, "PeriodEnd"))
.Last();
var customerAndOrders = context.Customers
.TemporalAsOf(customerDeletedOn.AddMilliseconds(-1))
.Include(e => e.Orders)
.Single();
context.Add(customerAndOrders);
context.SaveChanges();
来源:
https://devblogs.microsoft.com/dotnet/prime-your-flux-capacitor-sql-server-temporal-tables-in-ef-core-6-0/
https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-6.0/plan
https://github.com/dotnet/efcore/issues/4693
【讨论】:
以上是关于Net Core:实体框架和 SQL Server 时态表、自动脚手架的主要内容,如果未能解决你的问题,请参考以下文章
使用带有实体框架代码优先和 ASP.NET MVC 3 和 mvc miniprofiler 的 SQL Server CE 时出现问题
带有实体框架和 SQL Server 数据库的 ASP.NET MVC - 图像未显示在视图中......错误显示“无法将“字节”转换为“字符串”
同时将实体框架与 SQL Server 和 SQLite 数据库一起使用
在.NET Core类库中使用EF Core迁移数据库到SQL Server
.NET Core EF框架使用SQL server 2008数据库分页问题:Incorrect syntax near 'OFFSET'. Invalid usage of the