溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Entity?Framework?Core如何更新時間映射

發(fā)布時間:2022-03-25 13:35:14 來源:億速云 閱讀:210 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹了Entity Framework Core如何更新時間映射,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

時間字段

在真實的開發(fā)中,為了跟蹤數(shù)據(jù)的變化,一般會在數(shù)據(jù)表里面有CreatedTime和UpdatedTime兩列。CreatedTime表示創(chuàng)建時間,新增一條數(shù)據(jù)的時候,會更新CreatedTime列的值。UpdatedTime表示更新時間,更新數(shù)據(jù)的同時也會更新UpdatedTime列的值,這時候就需要對應(yīng)的映射來配置。我們修改Blog類,增加這兩個時間字段:

using System;

namespace EFCore.Model
{
    public  class Blog
    {
        public int Id { get; set; }
        public string Name { get; set; }

        /// <summary>
        /// 創(chuàng)建時間
        /// </summary>
        public DateTime CreatedTime { get; set; }

        /// <summary>
        /// 添加時間
        /// </summary>
        public DateTime UpdatedTime { get; set; }
    }
}

這時不做任何配置,使用遷移的方式生成數(shù)據(jù)庫,查看數(shù)據(jù)庫表結(jié)構(gòu):

Entity?Framework?Core如何更新時間映射

可以看到數(shù)據(jù)庫里面生成的是datetime2類型的,datetime2的精度非常高。但是一般情況下不使用datetime2高精度的,使用datetime就可以了,這時候就需要我們自己做映射來配置生成datetime類型。

修改數(shù)據(jù)上下文類,增加時間字段的映射配置,代碼如下:

using EFCore.Model;
using Microsoft.EntityFrameworkCore;

namespace EFCore.Data
{
    /// <summary>
    /// 數(shù)據(jù)上下文
    /// </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");
            // 將表名長度設(shè)置為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)
                // 設(shè)置列的類型是DATETIME
                 .HasColumnType("DATETIME")
                 // 設(shè)置列的默認值
                 .HasDefaultValueSql("GETDATE()");

                // 配置UpdatedTime字段
                p.Property(t => t.UpdatedTime)
                // 設(shè)置列的類型是DATETIME
                .HasColumnType("DATETIME")
                // 設(shè)置列的默認值
                .HasDefaultValueSql("GETDATE()");
            });

            base.OnModelCreating(modelBuilder);
        }

    }
}

在使用數(shù)據(jù)遷移的方式生成數(shù)據(jù)庫表,然后查看列的數(shù)據(jù)類型:

Entity?Framework?Core如何更新時間映射

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

Entity?Framework?Core如何更新時間映射

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

Entity?Framework?Core如何更新時間映射

可以看到:Name列的值已經(jīng)發(fā)生修改,但是UpdatedTime列的值卻沒有更新。但是我們想要的效果是數(shù)據(jù)更新的時候,UpdatedTime列的值也隨之更新,該怎么辦呢?有兩種方式解決這個問題。

1、使用計算列

這種方式是對UpdatedTime字段設(shè)置使用計算列,代碼如下:

using EFCore.Model;
using Microsoft.EntityFrameworkCore;

namespace EFCore.Data
{
    /// <summary>
    /// 數(shù)據(jù)上下文
    /// </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");
            // 將表名長度設(shè)置為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)
                // 設(shè)置列的類型是DATETIME
                 .HasColumnType("DATETIME")
                 // 設(shè)置列的默認值
                 .HasDefaultValueSql("GETDATE()");

                //// 配置UpdatedTime字段
                //p.Property(t => t.UpdatedTime)
                //// 設(shè)置列的類型是DATETIME
                //.HasColumnType("DATETIME")
                //// 設(shè)置列的默認值
                //.HasDefaultValueSql("GETDATE()");

                // 配置UpdatedTime字段
                p.Property(t => t.UpdatedTime)
                // 設(shè)置列的類型是DATETIME
                .HasColumnType("DATETIME")
                // 設(shè)置UpdatedTime字段使用計算列
                .HasComputedColumnSql("GETDATE()");
            });

            // 添加一條種子數(shù)據(jù)
            modelBuilder.Entity<Blog>().HasData(
                new Blog() 
                {
                    Id=1,
                  Name="ef core 3.1.2"
                });
            base.OnModelCreating(modelBuilder);
        }

    }
}

然后刪除數(shù)據(jù)庫,從新開始生成數(shù)據(jù)庫、新增數(shù)據(jù)、修改數(shù)據(jù)這三步,我們先看新增數(shù)據(jù)后的結(jié)果:

Entity?Framework?Core如何更新時間映射

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

Entity?Framework?Core如何更新時間映射

這時就會發(fā)現(xiàn):UpdatedTime列的值就會發(fā)生改變了。也會發(fā)現(xiàn),UpdatedTime列的數(shù)據(jù)類型是計算:

Entity?Framework?Core如何更新時間映射

2、重寫SaveChanges方法

還有一種方式是重寫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>
        /// 創(chuàng)建時間
        /// </summary>
        public DateTime CreatedTime { get; set; }

        /// <summary>
        /// 添加時間
        /// </summary>
        public DateTime UpdatedTime { get; set; }
    }
}

然后在數(shù)據(jù)上下文類里面重寫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)
// 設(shè)置列的類型是DATETIME
.HasColumnType("DATETIME")
// 設(shè)置列的默認值
.HasDefaultValueSql("GETDATE()");

這種方式就不能使用數(shù)據(jù)遷移了,要在代碼里面調(diào)用SaveChanges方法才可以實現(xiàn):

using EFCore.Data;
using EFCore.Model;
using System;

namespace EFCore.Con
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            // 實例化數(shù)據(jù)上下文對象
            EFDbContext dbContext = new EFDbContext();
            // 生成數(shù)據(jù)庫
            bool tfTrue = dbContext.Database.EnsureCreated();
            if (tfTrue)
            {
                Console.WriteLine("數(shù)據(jù)庫創(chuàng)建成功!");
            }
            else
            {
                Console.WriteLine("數(shù)據(jù)庫創(chuàng)建失敗!");
            }

            // 查詢Id為1的數(shù)據(jù)
            var blog = dbContext.Blogs.Find(1);
            // 更改表名稱
            blog.Name = "entity framework core 3.1.21212";
            dbContext.SaveChanges();
            Console.ReadKey();
        }
    }
}

數(shù)據(jù)庫效果:

Entity?Framework?Core如何更新時間映射

這樣也完成了更新。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Entity Framework Core如何更新時間映射”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI