這篇文章主要介紹了Entity Framework Core如何更新時間映射,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
在真實的開發中,為了跟蹤數據的變化,一般會在數據表里面有CreatedTime和UpdatedTime兩列。CreatedTime表示創建時間,新增一條數據的時候,會更新CreatedTime列的值。UpdatedTime表示更新時間,更新數據的同時也會更新UpdatedTime列的值,這時候就需要對應的映射來配置。我們修改Blog類,增加這兩個時間字段:
using System;
namespace EFCore.Model
{
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
/// <summary>
/// 創建時間
/// </summary>
public DateTime CreatedTime { get; set; }
/// <summary>
/// 添加時間
/// </summary>
public DateTime UpdatedTime { get; set; }
}
}這時不做任何配置,使用遷移的方式生成數據庫,查看數據庫表結構:

可以看到數據庫里面生成的是datetime2類型的,datetime2的精度非常高。但是一般情況下不使用datetime2高精度的,使用datetime就可以了,這時候就需要我們自己做映射來配置生成datetime類型。
修改數據上下文類,增加時間字段的映射配置,代碼如下:
using EFCore.Model;
using Microsoft.EntityFrameworkCore;
namespace EFCore.Data
{
/// <summary>
/// 數據上下文
/// </summary>
public class EFDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=EFTest;User ID=sa;Password=123456;");
}
public DbSet<Blog> Blogs { get; set; }
/// <summary>
/// 重寫OnModelCreating方法,配置映射
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 配置表名映射
modelBuilder.Entity<Blog>().ToTable("Blog");
// 將表名長度設置為250會報錯,表名最大長度限制為128
//var tableName = string.Join("", Enumerable.Repeat("t", 250).ToArray());
//modelBuilder.Entity<Blog>().ToTable(tableName);
modelBuilder.Entity<Blog>(p =>
{
// 配置CreatedTime字段
p.Property(t => t.CreatedTime)
// 設置列的類型是DATETIME
.HasColumnType("DATETIME")
// 設置列的默認值
.HasDefaultValueSql("GETDATE()");
// 配置UpdatedTime字段
p.Property(t => t.UpdatedTime)
// 設置列的類型是DATETIME
.HasColumnType("DATETIME")
// 設置列的默認值
.HasDefaultValueSql("GETDATE()");
});
base.OnModelCreating(modelBuilder);
}
}
}在使用數據遷移的方式生成數據庫表,然后查看列的數據類型:

這時候時間列的數據類型就是datetime類型了。在代碼里面給時間字段設置了默認值,我們添加一條種子數據,然后新增到數據庫,看看會不會自動生成默認值:

從截圖中可以看出:新增數據的時候,CreatedTime和UpdatedTime會自動賦當前時間的值。在修改剛才添加的種子數據,看看UdpatedTime列的值會不會更新:

可以看到:Name列的值已經發生修改,但是UpdatedTime列的值卻沒有更新。但是我們想要的效果是數據更新的時候,UpdatedTime列的值也隨之更新,該怎么辦呢?有兩種方式解決這個問題。
這種方式是對UpdatedTime字段設置使用計算列,代碼如下:
using EFCore.Model;
using Microsoft.EntityFrameworkCore;
namespace EFCore.Data
{
/// <summary>
/// 數據上下文
/// </summary>
public class EFDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=EFTest;User ID=sa;Password=123456;");
}
public DbSet<Blog> Blogs { get; set; }
/// <summary>
/// 重寫OnModelCreating方法,配置映射
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 配置表名映射
modelBuilder.Entity<Blog>().ToTable("Blog");
// 將表名長度設置為250會報錯,表名最大長度限制為128
//var tableName = string.Join("", Enumerable.Repeat("t", 250).ToArray());
//modelBuilder.Entity<Blog>().ToTable(tableName);
modelBuilder.Entity<Blog>(p =>
{
// 配置CreatedTime字段
p.Property(t => t.CreatedTime)
// 設置列的類型是DATETIME
.HasColumnType("DATETIME")
// 設置列的默認值
.HasDefaultValueSql("GETDATE()");
//// 配置UpdatedTime字段
//p.Property(t => t.UpdatedTime)
//// 設置列的類型是DATETIME
//.HasColumnType("DATETIME")
//// 設置列的默認值
//.HasDefaultValueSql("GETDATE()");
// 配置UpdatedTime字段
p.Property(t => t.UpdatedTime)
// 設置列的類型是DATETIME
.HasColumnType("DATETIME")
// 設置UpdatedTime字段使用計算列
.HasComputedColumnSql("GETDATE()");
});
// 添加一條種子數據
modelBuilder.Entity<Blog>().HasData(
new Blog()
{
Id=1,
Name="ef core 3.1.2"
});
base.OnModelCreating(modelBuilder);
}
}
}然后刪除數據庫,從新開始生成數據庫、新增數據、修改數據這三步,我們先看新增數據后的結果:

可以看到,CreatedTime和UpdatedTime這時會有誤差,但是誤差是秒以內可以接受的。我們在看修改后的結果:

這時就會發現:UpdatedTime列的值就會發生改變了。也會發現,UpdatedTime列的數據類型是計算:

還有一種方式是重寫SaveChanges()方法。
我們首先在實體類庫里面定義一個IUpdatedable接口:
using System;
namespace EFCore.Model
{
public interface IUpdatedable
{
DateTime UpdatedTime { get; set; }
}
}然后Blog類繼承自這個接口:
using System;
namespace EFCore.Model
{
public class Blog:IUpdatedable
{
public int Id { get; set; }
public string Name { get; set; }
/// <summary>
/// 創建時間
/// </summary>
public DateTime CreatedTime { get; set; }
/// <summary>
/// 添加時間
/// </summary>
public DateTime UpdatedTime { get; set; }
}
}然后在數據上下文類里面重寫SaveChanges方法:
public override int SaveChanges()
{
var entries = ChangeTracker.Entries().ToList();
var updateEntries = entries.Where(e => (e.Entity is IUpdatedable)
&& e.State == EntityState.Modified).ToList();
updateEntries.ForEach(e =>
{
((IUpdatedable)e.Entity).UpdatedTime = DateTime.Now;
});
return base.SaveChanges();
}同時修改UpdatedTime字段不是計算列,賦默認值:
// 配置UpdatedTime字段
p.Property(t => t.UpdatedTime)
// 設置列的類型是DATETIME
.HasColumnType("DATETIME")
// 設置列的默認值
.HasDefaultValueSql("GETDATE()");這種方式就不能使用數據遷移了,要在代碼里面調用SaveChanges方法才可以實現:
using EFCore.Data;
using EFCore.Model;
using System;
namespace EFCore.Con
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
// 實例化數據上下文對象
EFDbContext dbContext = new EFDbContext();
// 生成數據庫
bool tfTrue = dbContext.Database.EnsureCreated();
if (tfTrue)
{
Console.WriteLine("數據庫創建成功!");
}
else
{
Console.WriteLine("數據庫創建失敗!");
}
// 查詢Id為1的數據
var blog = dbContext.Blogs.Find(1);
// 更改表名稱
blog.Name = "entity framework core 3.1.21212";
dbContext.SaveChanges();
Console.ReadKey();
}
}
}數據庫效果:

這樣也完成了更新。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Entity Framework Core如何更新時間映射”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。