国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

asp.net core EFCore 屬性配置與DbContext

這篇具有很好參考價(jià)值的文章主要介紹了asp.net core EFCore 屬性配置與DbContext。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

asp.net core EFCore 屬性配置與DbContext

前言

Entity Framework (EF) Core 是輕量化、可擴(kuò)展、開源和跨平臺(tái)版的常用 Entity Framework 數(shù)據(jù)訪問技術(shù)。用于程序中的class類和數(shù)據(jù)庫(kù)中的表互相之間建立映射關(guān)系。在學(xué)習(xí)過程中,EFCore中的屬性配置顯的尤為重要它是學(xué)習(xí)好asp.net core的基礎(chǔ)是配置數(shù)據(jù)庫(kù)表結(jié)構(gòu)的重要基石。本篇內(nèi)容為學(xué)習(xí)與整理微軟文檔(MicrosoftDoc)筆者認(rèn)為重要部分具體內(nèi)容參見: Microsoft Build

EF Core 可用作對(duì)象關(guān)系映射程序 (O/RM),這可以實(shí)現(xiàn)以下兩點(diǎn):

  1. 使 .NET 開發(fā)人員能夠使用 .NET 對(duì)象處理數(shù)據(jù)庫(kù)。
  2. 無(wú)需再像通常那樣編寫大部分?jǐn)?shù)據(jù)訪問代碼。

EF Core 支持多個(gè)數(shù)據(jù)庫(kù)引擎,可通過名為數(shù)據(jù)庫(kù)提供程序的插件庫(kù)訪問許多不同的數(shù)據(jù)庫(kù)。
EF Core 提供程序通??绱我姹竟ぷ鳎豢缰饕姹竟ぷ?。 例如,針對(duì) EF Core 2.1 發(fā)布的提供程序應(yīng)用于 EF Core 2.2,但不適用于 EF Core 3.0。

使用 Entity Framework Core (EF Core) 時(shí)的典型工作單元包括:

1、創(chuàng)建 DbContext 實(shí)例

根據(jù)上下文跟蹤實(shí)體實(shí)例。 實(shí)體將在以下情況下被跟蹤

  1. 正在從查詢返回
  2. 正在添加或附加到上下文
  3. 根據(jù)需要對(duì)所跟蹤的實(shí)體進(jìn)行更改以實(shí)現(xiàn)業(yè)務(wù)規(guī)則
  4. 調(diào)用 SaveChanges 或 SaveChangesAsync。 EF Core 檢測(cè)所做的更改,并將這些更改寫入數(shù)據(jù)庫(kù)。
2、 釋放 DbContext 實(shí)例
3、重要
  1. 使用后釋放 DbContext 非常重要。 這可確保釋放所有非托管資源,并注銷任何事件或其他掛鉤,以防止在實(shí)例保持引用時(shí)出現(xiàn)內(nèi)存泄漏。
  2. DbContext 不是線程安全的。 不要在線程之間共享上下文。 請(qǐng)確保在繼續(xù)使用上下文實(shí)例之前,等待所有異步調(diào)用。 EF Core
  3. 代碼引發(fā)的 InvalidOperationException 可以使上下文進(jìn)入不可恢復(fù)的狀態(tài)。此類異常指示程序錯(cuò)誤,并且不旨在從其中恢復(fù)。

一、 ASP.NET Core 依賴關(guān)系注入中的 DbContext

可以使用 Startup.cs 的 ConfigureServices 方法中的 AddDbContext 將 EF Core 添加到此配置。 例如:

C#。

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddDbContext<ApplicationDbContext>(
        options => options.UseSqlServer("name=ConnectionStrings:DefaultConnection"));
}

此示例將名為 ApplicationDbContext 的 DbContext 子類注冊(cè)為 ASP.NET Core 應(yīng)用程序服務(wù)提供程序(也稱為依賴關(guān)系注入容器)中的作用域服務(wù)。 上下文配置為使用 SQL Server 數(shù)據(jù)庫(kù)提供程序,并將從 ASP.NET Core 配置讀取連接字符串。 在 ConfigureServices 中的何處調(diào)用 AddDbContext 通常不重要。
ApplicationDbContext 類必須公開具有 DbContextOptions &lt< ApplicationDbContext> &gt參數(shù)的公共構(gòu)造函數(shù)。 這是將 AddDbContext 的上下文配置傳遞到 DbContext 的方式。 例如:
C#。

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

然后,ApplicationDbContext 可以通過構(gòu)造函數(shù)注入在 ASP.NET Core 控制器或其他服務(wù)中使用。 例如:
c#

public class MyController
{
    private readonly ApplicationDbContext _context;

    public MyController(ApplicationDbContext context)
    {
        _context = context;
    }
}

最終結(jié)果是為每個(gè)請(qǐng)求創(chuàng)建一個(gè) ApplicationDbContext 實(shí)例,并傳遞給控制器,以在請(qǐng)求結(jié)束后釋放前執(zhí)行工作單元。

二、DbContext 初始化與創(chuàng)建并配置模型

2.1、 DbContext 初始化

可以按照常規(guī)的 .NET 方式構(gòu)造 DbContext 實(shí)例,例如,使用 C# 中的 new。 可以通過重寫 OnConfiguring 方法或通過將選項(xiàng)傳遞給構(gòu)造函數(shù)來執(zhí)行配置。 例如:

  • 重寫 OnConfiguring 方法 C#。
public class ApplicationDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test");
    }
}

通過此模式,還可以輕松地通過 DbContext 構(gòu)造函數(shù)傳遞配置(如連接字符串)。 例如:

  • DbContext 構(gòu)造函數(shù)傳遞配置 C#。
public class ApplicationDbContext : DbContext
{
    private readonly string _connectionString;

    public ApplicationDbContext(string connectionString)
    {
        _connectionString = connectionString;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(_connectionString);
    }
}

或者,可以使用 DbContextOptionsBuilder 創(chuàng)建 DbContextOptions 對(duì)象,然后將該對(duì)象傳遞到 DbContext 構(gòu)造函數(shù)。 這使得為依賴關(guān)系注入配置的 DbContext 也能顯式構(gòu)造。 例如,使用上述為 ASP.NET Core 的 Web 應(yīng)用定義的 ApplicationDbContext 時(shí):
ApplicationDbContext C#

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

2.2、創(chuàng)建并配置模型

Entity Framework Core 使用一組約定來根據(jù)實(shí)體類的形狀生成模型。 可指定其他配置以補(bǔ)充和/或替代約定的內(nèi)容。

模型配置主要分為兩種方法:

  • FluentAPI
  • 數(shù)據(jù)注解

2.2.1使用 fluent API 配置模型

可在派生上下文中替代 OnModelCreating 方法,并使用 ModelBuilder API 來配置模型。 此配置方法最為有效,并可在不修改實(shí)體類的情況下指定配置。 Fluent API 配置具有最高優(yōu)先級(jí),并將替代約定和數(shù)據(jù)注釋。

  • Fluent API 配置 C#。
using Microsoft.EntityFrameworkCore;

namespace EFModeling.EntityProperties.FluentAPI.Required;

internal class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    #region Required
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property(b => b.Url)
            .IsRequired();
    }
    #endregion
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

2.2.2分組配置

如果你有多個(gè)表需要配置。為了減小 OnModelCreating 方法的大小,可以將實(shí)體類型的所有配置提取到實(shí)現(xiàn) IEntityTypeConfiguration 的單獨(dú)類中。

  • IEntityTypeConfiguration接口 C#。
public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
{
    public void Configure(EntityTypeBuilder<Blog> builder)
    {
        builder
            .Property(b => b.Url)
            .IsRequired();
    }
}

然后,只需從 OnModelCreating 調(diào)用 Configure 方法。

  • OnModelCreating 調(diào)用 Configure 方法 C#。
protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
 
     new BlogEntityTypeConfiguration().Configure(modelBuilder.Entity<Blog>());   
 }

也可以在給定程序集中應(yīng)用實(shí)現(xiàn) IEntityTypeConfiguration 的類型中指定的所有配置。

  • IEntityTypeConfiguration 的類型中指定的所有配置 C#。
protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
//modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);  
  modelBuilder.ApplyConfigurationsFromAssembly(typeof(BlogEntityTypeConfiguration).Assembly);
 }

應(yīng)用配置的順序是不確定的,因此僅當(dāng)順序不重要時(shí)才應(yīng)使用此方法。

2.2.3使用數(shù)據(jù)注釋來配置模型

也可將特性(稱為數(shù)據(jù)注釋)應(yīng)用于類和屬性。 數(shù)據(jù)注釋會(huì)替代約定,但會(huì)被 Fluent API 配置替代。

  • 數(shù)據(jù)注釋來配置模型 C#
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;

namespace EFModeling.EntityProperties.DataAnnotations.Annotations;

internal class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
}

[Table("Blogs")]
public class Blog
{
    public int BlogId { get; set; }

    [Required]
    public string Url { get; set; }
}

三、實(shí)體類型

在上下文中包含一種類型的 DbSet 意味著它包含在 EF Core 的模型中;我們通常將此類類型稱為實(shí)體。 EF Core 可以從/向數(shù)據(jù)庫(kù)中讀取和寫入實(shí)體實(shí)例,如果使用的是關(guān)系數(shù)據(jù)庫(kù),EF Core 可以通過遷移為實(shí)體創(chuàng)建表。
按照約定,上下文的 DbSet 屬性中公開的類型作為實(shí)體包含在模型中。 還包括在 OnModelCreating 方法中指定的實(shí)體類型,以及通過遞歸探索其他發(fā)現(xiàn)的實(shí)體類型的導(dǎo)航屬性找到的任何類型。
下面的代碼示例中包含了所有類型:

  • 包含 Blog,因?yàn)樗谏舷挛牡?DbSet 屬性中公開。
  • 包含 Post,因?yàn)樗峭ㄟ^ Blog.Posts 導(dǎo)航屬性發(fā)現(xiàn)的。
  • 包含 AuditEntry因?yàn)樗?OnModelCreating 中指定的。
    Fluent API C#。
internal class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<AuditEntry>();
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

public class AuditEntry
{
    public int AuditEntryId { get; set; }
    public string Username { get; set; }
    public string Action { get; set; }
}

四、實(shí)體屬性

模型中的每個(gè)實(shí)體類型都有一組屬性,EF Core 將從數(shù)據(jù)庫(kù)中讀取和寫入這些屬性。 如果使用的是關(guān)系數(shù)據(jù)庫(kù),實(shí)體屬性將映射到表列。

4.1、列名

按照約定,使用關(guān)系數(shù)據(jù)庫(kù)時(shí),實(shí)體屬性將映射到與屬性同名的表列。如果希望配置具有不同名稱的列,可以按以下代碼片段進(jìn)行操作:
Fluent API C#。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Id)
        .HasColumnName("id");//數(shù)據(jù)庫(kù)表字段為英文小寫
}

4.2、列數(shù)據(jù)類型

使用關(guān)系數(shù)據(jù)庫(kù)時(shí),數(shù)據(jù)庫(kù)提供程序會(huì)根據(jù)屬性的 .NET 類型選擇數(shù)據(jù)類型。 它還會(huì)考慮其他元數(shù)據(jù),例如配置的最大長(zhǎng)度、屬性是否是主鍵的一部分等等。
例如,SQL Server 將 DateTime 屬性映射到 datetime2(7) 列,將 string 屬性映射到 nvarchar(max) 列(或?qū)τ谟米麈I的屬性,映射到 nvarchar(450))。
還可以配置列以指定列的確切數(shù)據(jù)類型。 例如,以下代碼將 Url 配置為非 unicode 字符串,其最大長(zhǎng)度為 200,并將 Rating 配置為十進(jìn)制,其精度為 5,小數(shù)位數(shù)為 2:
Fluent API C#。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>(
        eb =>
        {
            eb.Property(b => b.Url).HasColumnType("varchar(200)");
            eb.Property(b => b.Rating).HasColumnType("decimal(5, 2)");
        });
}

4.3、最大長(zhǎng)度

配置最大長(zhǎng)度可向數(shù)據(jù)庫(kù)提供程序提供有關(guān)為給定屬性選擇適當(dāng)列數(shù)據(jù)類型的提示。 最大長(zhǎng)度僅適用于數(shù)組數(shù)據(jù)類型,如 string 和 byte[]。
在下面的示例中,將最大長(zhǎng)度配置為 500 將導(dǎo)致在 SQL Server 上創(chuàng)建 nvarchar(500) 類型的列:
下面展示一些 內(nèi)聯(lián)代碼片

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Url)
        .HasMaxLength(500);
}

4.3、精度和小數(shù)位數(shù)

某些關(guān)系數(shù)據(jù)類型支持精度和小數(shù)位數(shù) Facet,它們用于控制可以存儲(chǔ)哪些值,以及列需要多少存儲(chǔ)。 哪些數(shù)據(jù)類型支持精度和小數(shù)位數(shù)取決于數(shù)據(jù)庫(kù),但在大多數(shù)數(shù)據(jù)庫(kù)中,decimal 和 DateTime 類型支持這些 Facet。 對(duì)于 decimal 屬性,精度用于定義表示列將包含的任何值所需的最大位數(shù),小數(shù)位數(shù)用于定義所需的最大小數(shù)位數(shù)。 對(duì)于 DateTime 屬性,精度用于定義表示秒的小數(shù)部分所需的最大位數(shù),不使用小數(shù)位數(shù)。
在以下示例中,將 Score 屬性配置為精度為 14 和小數(shù)位數(shù)為 2 將導(dǎo)致在 SQL Server 上創(chuàng)建 decimal(14,2) 類型的列,將 LastUpdated 屬性配置為精度為 3 將導(dǎo)致創(chuàng)建 datetime2(3) 類型的列:
C#。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Score)
        .HasPrecision(14, 2);

    modelBuilder.Entity<Blog>()
        .Property(b => b.LastUpdated)
        .HasPrecision(3);
}

EF Core 5.0 中引入了用于配置精度和小數(shù)位數(shù)的 Fluent API。如果不先定義精度,則永遠(yuǎn)不會(huì)定義小數(shù)位數(shù),因此用于定義小數(shù)位數(shù)的 Fluent API 為 HasPrecision(precision, scale)。

4.4、Unicode

在某些關(guān)系數(shù)據(jù)庫(kù)中,存在不同的類型來表示 Unicode 和非 Unicode 文本數(shù)據(jù)。 例如,在 SQL Server 中,nvarchar(x)用于表示 UTF-16 中的 Unicode 數(shù)據(jù),而varchar(x)用于表示非 Unicode 數(shù)據(jù) (,但請(qǐng)參閱有關(guān) UTF-8 支持) SQL Server說明。 對(duì)于不支持此概念的數(shù)據(jù)庫(kù),配置此概念將不起作用。

默認(rèn)情況下,文本屬性配置為 Unicode。 可以將列配置為非 Unicode,如下所示:
C#。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Book>()
        .Property(b => b.Isbn)
        .IsUnicode(false);
}

4.4必需和可選屬性

如果屬性包含 null 是有效的,則該屬性被視為可選屬性。 如果 null 不是要分配給屬性的有效值,則它被視為必需屬性。映射到關(guān)系數(shù)據(jù)庫(kù)架構(gòu)時(shí),必需屬性創(chuàng)建為不可為 null 的列,可選屬性創(chuàng)建為可為 null 的列。
按照約定,其 .NET 類型可包含 null 的屬性將配置為可選屬性,而 .NET 類型不能包含 null 的屬性將配置為必需屬性。例如,將具有 .NET 值類型的所有屬性 (int decimal bool、) 等等配置為必需,并且所有具有可為 null 的 .NET值類型 (int?decimal?等bool?屬性都配置為可選。
C# 8 引入了一項(xiàng)名為可為 null 引用類型 (NRT) 的新功能,該功能允許對(duì)引用類型進(jìn)行批注,指示引用類型能否包含 null。此功能默認(rèn)處于禁用狀態(tài),它會(huì)通過以下方式影響 EF Core的行為:
  • 如果禁用了可為 null 的引用類型(默認(rèn)設(shè)置),則具有 .NET 引用類型的所有屬性都按約定配置為可選屬性(例如string)。
  • 如果啟用了可為 null 的引用類型,則基于屬性的 .NET 類型的 C# 為 Null 性來配置屬性:string? 將配置為可選屬性,但 string 將配置為必需屬性。
  • 以下示例演示一個(gè)具有必需和可選屬性的實(shí)體類型,分別說明了可為 null的引用功能在禁用(默認(rèn)設(shè)置)時(shí)和啟用時(shí)的情況:

禁用了可為 null 的引用類型C#(默認(rèn)設(shè)置)。

public class CustomerWithoutNullableReferenceTypes
{
    public int Id { get; set; }

    [Required] // 根據(jù)需要配置所需的數(shù)據(jù)注釋  
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; } // 根據(jù)需要配置所需的數(shù)據(jù)注釋

    public string MiddleName { get; set; } // 可選的按照慣例 
}

啟用了可為 null 的引用類型 C#可為 null 引用類型 (NRT)

public class Customer
{
    public int Id { get; set; }
    public string FirstName { get; set; } // Required by convention
    public string LastName { get; set; } // Required by convention
    public string? MiddleName { get; set; } // Optional by convention

    //注意以下構(gòu)造函數(shù)綁定的使用,它避免了對(duì)未初始化的非空屬性的編譯警告。
    public Customer(string firstName, string lastName, string? middleName = null)
    {
        FirstName = firstName;
        LastName = lastName;
        MiddleName = middleName;
    }
}

五、OnModelCreating配置

5.1、顯式配置

按約定為可選屬性的屬性可以配置為必需屬性,如下所示:

C#

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Url)
        .IsRequired();
}

5.2、默認(rèn)值

在關(guān)系數(shù)據(jù)庫(kù)中,可以為列配置默認(rèn)值;如果插入的行沒有該列的值,則將使用默認(rèn)值。

可以在屬性上配置默認(rèn)值: C"

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Rating)
        .HasDefaultValue(3);
}

還可以指定用于計(jì)算默認(rèn)值的 SQL 片段: C#。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Created)
        .HasDefaultValueSql("getdate()");
}

5.3、計(jì)算列

在大多數(shù)關(guān)系數(shù)據(jù)庫(kù)中,可以將列配置為在數(shù)據(jù)庫(kù)中計(jì)算其值,并且通常使用引用其他列的表達(dá)式:
C#。

modelBuilder.Entity<Person>()
    .Property(p => p.DisplayName)
    .HasComputedColumnSql("[LastName] + ', ' + [FirstName]");

以上命令將創(chuàng)建一個(gè)虛擬計(jì)算列,每次從數(shù)據(jù)庫(kù)中提取時(shí)都會(huì)計(jì)算其值。 你也可以將計(jì)算列指定為存儲(chǔ)(有時(shí)稱為持久化)計(jì)算列,這意味著系統(tǒng)會(huì)在每次更新行時(shí)計(jì)算該列,并將其與常規(guī)列一起存儲(chǔ)在磁盤上:

  • EF Core 5.0 中添加了對(duì)創(chuàng)建存儲(chǔ)計(jì)算列的支持。 C#。
modelBuilder.Entity<Person>()
    .Property(p => p.NameLength)
    .HasComputedColumnSql("LEN([LastName]) + LEN([FirstName])", stored: true);

5.4、主鍵

  • 按照約定,如果應(yīng)用程序未提供值,則將類型為 short、int、long 或 Guid 的非復(fù)合主鍵設(shè)置為針對(duì)插入的實(shí)體生成值。
    數(shù)據(jù)庫(kù)提供程序通常負(fù)責(zé)必要的配置;例如,SQL Server 中的數(shù)字主鍵會(huì)自動(dòng)設(shè)置為 IDENTITY 列。
  • 根據(jù)約定,名為 Id 或 Id 的屬性將被配置為實(shí)體的主鍵。
    可將單個(gè)屬性配置為實(shí)體的主鍵,如下所示:
    下面展示一些 C#。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasKey(c => c.LicensePlate);
}

還可將多個(gè)屬性配置為實(shí)體的鍵 - 這稱為組合鍵。 組合鍵只能使用 Fluent API 進(jìn)行配置;約定永遠(yuǎn)不會(huì)設(shè)置組合鍵,并且不能使用數(shù)據(jù)注釋來配置組合鍵。
下面展示一些 內(nèi)聯(lián)代碼片

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasKey(c => new { c.State, c.LicensePlate });
}

5.5、主鍵名稱

根據(jù)約定,在關(guān)系數(shù)據(jù)庫(kù)上,主鍵使用名稱 PK_ 進(jìn)行創(chuàng)建。 可按如下方式配置主鍵約束的名稱:
主鍵名稱 "HasName"C#。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasKey(b => b.BlogId)
        .HasName("PrimaryKey_BlogId");
}
  • 雖然 EF Core 支持使用任何基元類型的屬性作為主鍵(包括 string、Guid、byte[]
    等),但并非所有數(shù)據(jù)庫(kù)都支持所有類型作為鍵。 在某些情況下,鍵值可以自動(dòng)轉(zhuǎn)換為支持的類型,否則應(yīng)手動(dòng)指定轉(zhuǎn)換。

  • 向上下文添加新實(shí)體時(shí),鍵屬性必須始終具有非默認(rèn)值,但某些類型將由數(shù)據(jù)庫(kù)生成。 在這種情況下,當(dāng)添加實(shí)體以用于跟蹤時(shí),EF將嘗試生成一個(gè)臨時(shí)值。 調(diào)用 SaveChanges 后,臨時(shí)值將替換為數(shù)據(jù)庫(kù)生成的值。

  • 如果鍵屬性的值由數(shù)據(jù)庫(kù)生成,并且在添加實(shí)體時(shí)指定了非默認(rèn)值,則 EF 將假定該實(shí)體已存在于數(shù)據(jù)庫(kù)中,并嘗試更新它,而不是插入新的實(shí)體。
    若要避免這種情況,請(qǐng)禁用值生成。

六、值生成

6.1、 顯式配置值生成

EF Core 會(huì)自動(dòng)為主鍵設(shè)置值生成 - 但我們可能希望對(duì)非鍵屬性執(zhí)行相同的操作。 你可以將任何屬性配置為針對(duì)插入的實(shí)體生成其值,如下所示:

  • 使用ValueGeneratedOnAdd C#。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Inserted)
        .ValueGeneratedOnAdd();
}

同樣,可以將屬性配置為在添加或更新時(shí)生成其值:

  • 使用ValueGeneratedOnAddOrUpdate C#
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.LastUpdated)
        .ValueGeneratedOnAddOrUpdate();
}
警告
  • 與默認(rèn)值或計(jì)算列不同,我們沒有指定值的生成方式;這取決于所使用的數(shù)據(jù)庫(kù)提供程序。
    數(shù)據(jù)庫(kù)提供程序可能會(huì)自動(dòng)為某些屬性類型設(shè)置值生成,但其他屬性類型可能需要你手動(dòng)設(shè)置值的生成方式。
  • 例如,在 SQL Server 上,如果 GUID 屬性配置為在添加時(shí)生成值,提供程序會(huì)自動(dòng)在客戶端執(zhí)行值生成,并使用算法生成最佳順序GUID 值。 但是,在 ValueGeneratedOnAdd DateTime 屬性上指定 將不起作用 。
  • 同樣,配置為在添加或更新時(shí)生成值并標(biāo)記為并發(fā)標(biāo)記的 byte[] 屬性將設(shè)置為 rowversion 數(shù)據(jù)類型,以便在數(shù)據(jù)庫(kù)中自動(dòng)生成值。但是,指定 ValueGeneratedOnAdd 不起作用。
  • 根據(jù)所使用的數(shù)據(jù)庫(kù)提供程序,值可能由 EF 在客戶端生成或在數(shù)據(jù)庫(kù)中生成。 如果值是由數(shù)據(jù)庫(kù)生成的,那么 EF可能會(huì)在你將實(shí)體添加到上下文時(shí)分配一個(gè)臨時(shí)值;在 SaveChanges() 期間,此臨時(shí)值將替換為數(shù)據(jù)庫(kù)生成的值。

6.2、日期/時(shí)間值生成

一個(gè)常見的請(qǐng)求是讓數(shù)據(jù)庫(kù)列包含第一次插入列的日期/時(shí)間(添加時(shí)生成的值)或上次更新列的日期/時(shí)間(添加或更新時(shí)生成的值)。 由于可通過各種策略執(zhí)行此操作,因此 EF Core 提供程序通常不會(huì)為日期/時(shí)間列自動(dòng)設(shè)置值生成 - 你必須自行配置。

6.2.1、創(chuàng)建時(shí)間戳

若要將日期/時(shí)間列配置為包含行的創(chuàng)建時(shí)間戳,通常需要使用適當(dāng)?shù)?SQL 函數(shù)來配置默認(rèn)值。 例如,在 SQL Server 上,你可以使用以下命令:
創(chuàng)建時(shí)間戳 C#。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Created)
        .HasDefaultValueSql("getdate()");
}

請(qǐng)確保選擇適當(dāng)?shù)暮瘮?shù),因?yàn)榭赡艽嬖诙鄠€(gè)函數(shù)(例如 GETDATE() 與 GETUTCDATE())。

6.2.1、更新時(shí)間戳

盡管存儲(chǔ)計(jì)算列看起來非常適合管理上次更新時(shí)間戳,但數(shù)據(jù)庫(kù)通常不允許在計(jì)算列中指定諸如 GETDATE() 之類的函數(shù)。 作為替代方法,你可以設(shè)置一個(gè)數(shù)據(jù)庫(kù)觸發(fā)器來達(dá)到同樣的效果:
更新時(shí)間戳 C#

CREATE TRIGGER [dbo].[Blogs_UPDATE] ON [dbo].[Blogs]
    AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;

    DECLARE @Id INT

    SELECT @Id = INSERTED.BlogId
    FROM INSERTED

    UPDATE dbo.Blogs
    SET LastUpdated = GETDATE()
    WHERE BlogId = @Id
END
6.3、替代值生成

盡管為屬性配置了值生成,但在許多情況下,你仍然可以為其顯式指定一個(gè)值。 此操作能否真正起作用取決于已配置的特定值生成機(jī)制;雖然你可以指定顯式值而不是使用列的默認(rèn)值,但不能對(duì)計(jì)算列執(zhí)行相同的操作。

若要使用顯式值替代值生成,只需將屬性設(shè)置為該屬性類型的 CLR 默認(rèn)值(string 為 null,int 為 0,Guid 為 Guid.Empty,等等)以外的任意值。

6.3.1、將顯式值插入 IDENTITY 列中

默認(rèn)情況下,嘗試將顯式值插入 SQL Server IDENTITY 會(huì)失敗,因?yàn)镾QL Server 不允許將顯式值插入 IDENTITY 列中。 為此,必須在調(diào)用 SaveChanges() 之前手動(dòng)啟用 IDENTITY_INSERT,如下所示:

啟用 IDENTITY_INSERT C#。文章來源地址http://www.zghlxwxcb.cn/news/detail-466494.html

using (var context = new ExplicitIdentityValuesContext())
{
    context.Blogs.Add(new Blog { BlogId = 100, Url = "http://blog1.somesite.com" });
    context.Blogs.Add(new Blog { BlogId = 101, Url = "http://blog2.somesite.com" });

    context.Database.OpenConnection();
    try
    {
        //啟用 IDENTITY_INSERT 開
        context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Blogs ON");
        context.SaveChanges();
        //啟用 IDENTITY_INSERT 關(guān)
        context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Blogs OFF");
    }
    finally
    {
        context.Database.CloseConnection();
    }
}

到了這里,關(guān)于asp.net core EFCore 屬性配置與DbContext的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • ASP.Net Core Web Api+EFCore+MySql實(shí)現(xiàn)動(dòng)態(tài)查詢(保姆教學(xué))

    ASP.Net Core Web Api+EFCore+MySql實(shí)現(xiàn)動(dòng)態(tài)查詢(保姆教學(xué))

    本文會(huì)詳細(xì)講解如何從打開文件到第一個(gè)API開發(fā)完成,過程十分詳細(xì),是基于學(xué)習(xí)入門。 現(xiàn)在讓我們開始吧! 打開VS(演示用的Visual Studio2022) 第一步我們選擇創(chuàng)建新項(xiàng)目? ?第二步 選擇開發(fā)語(yǔ)言以及應(yīng)用程序 我們選擇C# -所有平臺(tái)-Web?API.找到 ASP.NET Core Web API 應(yīng)用 ? 這里應(yīng)用

    2024年02月12日
    瀏覽(18)
  • .NET Core/.NET6 使用DbContext 連接數(shù)據(jù)庫(kù),SqlServer

    .NET Core/.NET6 使用DbContext 連接數(shù)據(jù)庫(kù),SqlServer

    安裝以下NuGet包 Microsoft.EntityFrameworkCore.SqlServer:SQL server 需要添加包 Microsoft.EntityFrameworkCore.Tools Newtonsoft.Json:用于Json格式轉(zhuǎn)換 創(chuàng)建一個(gè)實(shí)體類來表示數(shù)據(jù)庫(kù)表。在項(xiàng)目中創(chuàng)建一個(gè)名為Customer.cs的文件,并添加以下代碼 創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)上下文類,用于定義實(shí)體類和數(shù)據(jù)庫(kù)連接

    2024年02月07日
    瀏覽(26)
  • ASP.NET Core —配置系統(tǒng)

    ASP.NET Core —配置系統(tǒng)

    一個(gè)應(yīng)用要運(yùn)行起來,往往需要讀取很多的預(yù)設(shè)好的配置信息,根據(jù)約定好的信息或方式執(zhí)行一定的行為。 配置的本質(zhì)就是軟件運(yùn)行的參數(shù),在一個(gè)軟件實(shí)現(xiàn)中需要的參數(shù)非常多,如果我們以 Hard Code (硬編碼)的方式寫在應(yīng)用代碼中,這樣配置就會(huì)很亂,而且后續(xù)也不容易修

    2024年02月08日
    瀏覽(20)
  • ASP.NET Core 配置系列一

    ASP.NET Core 配置系列一

    A S P . N E T ? C o r e ? 配 置 主 要 通 過 這 3 個(gè) 文 件 設(shè) 置 : 1 ? 項(xiàng) 目 文 件 也 叫 . c s p r o j ? 文 件 2 ? P r o g r a m . c s 3 ? a p p s e t t i n g s . j s o n 這 些 配 置 告 訴 A S P . N E T ? C o r e ? 應(yīng) 用 程 序 基 于 用 戶 的 交 互 是 如 何 工 作 的, 在 本 節(jié) 中 我 們 理 解 A S P .

    2024年02月03日
    瀏覽(99)
  • ASP.NET Core 8 的配置類 Configuration

    Configuration 可以從兩個(gè)途徑設(shè)置: WebApplication創(chuàng)建的對(duì)象app.Configuration 屬性 WebApplicationBuilder 創(chuàng)建的 builder.Configuration 屬性 app的Configuration優(yōu)先級(jí)更高,host Configuration作為替補(bǔ)配置,因?yàn)閍pp運(yùn)行在host之上。 每種方式都提供了非常豐富的配置選擇,可用于各種場(chǎng)景,以便在開發(fā)環(huán)

    2024年02月11日
    瀏覽(17)
  • asp.net core在發(fā)布時(shí)排除配置文件

    使用命令發(fā)布 dotnet restore dotnet publish -c Release?-r win-x64 -o \\\"D:services\\\"? 這樣發(fā)布總是是將配置文件覆蓋? 這時(shí)候打開項(xiàng)目.csproj新增配置文件

    2024年04月24日
    瀏覽(16)
  • Asp .Net Core 系列: 集成 CORS跨域配置

    Asp .Net Core 系列: 集成 CORS跨域配置

    CORS,全稱是“跨源資源共享”(Cross-Origin Resource Sharing),是一種Web應(yīng)用程序的安全機(jī)制,用于控制不同源的資源之間的交互。 在Web應(yīng)用程序中,CORS定義了一種機(jī)制,通過該機(jī)制,瀏覽器能夠限制哪些外部網(wǎng)頁(yè)可以訪問來自不同源的資源。源由協(xié)議、域名和端口組成。當(dāng)一

    2024年01月24日
    瀏覽(114)
  • 如何在 ASP.NET Core 配置請(qǐng)求超時(shí)中間件

    如何在 ASP.NET Core 配置請(qǐng)求超時(shí)中間件

    本文參考官方文檔,使用Asp.net core 8.0 的最小API 模板項(xiàng)目,配置超時(shí)中間件。 超時(shí)中間件可用于所有類型的ASP.NET Core應(yīng)用:最小 API、帶控制器的 Web API、MVC 和 Razor Pages。請(qǐng)求超時(shí)的屬性位于命名空間 Microsoft.AspNetCore.Http.Timeouts 中。 需要注意的是,當(dāng)應(yīng)用在調(diào)試模式下運(yùn)行時(shí)

    2024年01月20日
    瀏覽(93)
  • ASP.NET Core 3.1系列(4)——讀寫配置文件appsettings.json

    ASP.NET Core 3.1系列(4)——讀寫配置文件appsettings.json

    在大多數(shù)的應(yīng)用程序中,一些參數(shù)需要寫在配置文件里,以此增加系統(tǒng)的靈活性。在 ASP.NET 時(shí)代,配置參數(shù)一般會(huì)寫在 web.config 文件中,其本質(zhì)上是對(duì) XML 文件的讀取和寫入。而在 ASP.NET Core 中,配置文件變成了 appsettings.json 文件。相較于 XML , JSON 文件更加輕量且靈活,下面

    2024年02月06日
    瀏覽(26)
  • .net core 多項(xiàng)目中使用EFCore

    .net core 多項(xiàng)目中使用EFCore

    類庫(kù)一級(jí)項(xiàng)目使用.net core 3.1 框架 其中EFCore是和數(shù)據(jù)庫(kù)交互的 MultiCore 注入EFCore中的DBContext與數(shù)據(jù)庫(kù)交互 主要為了解決多項(xiàng)目中數(shù)據(jù)庫(kù)遷移失敗問題 EFCore 工程安裝如下包 MultiCore 安裝如下 EFCore person.cs personconfig.cs EFDbcontext.cs EFDbContextFac .cs 這是關(guān)鍵,但是這僅僅在開發(fā)環(huán)境下

    2024年02月07日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包