1. 程式人生 > >asp.net core系列 25 EF模型配置(隱藏屬性)

asp.net core系列 25 EF模型配置(隱藏屬性)

align etime target save pri avi img 狀態 core

一. 隱藏屬性概述

  隱藏屬性也叫影子屬性,該屬性不是在.net實體類中定義的屬性,而是在EFCore模型中為該實體類型定義的屬性。這些屬性的值和狀態完全在變更跟蹤器中維護。它有二個功能:(1)當數據庫中某些字段不想映射到實體類上公開的屬性時,隱藏屬性非常有用。(2)隱藏屬性通常是用於外鍵屬性,其中兩個實體之間的關系由數據庫中的外鍵值表示,但是兩個實體關系是使用實體類型之間的導航屬性進行管理(這個在下面約定中講到)。

  隱藏屬性值可以通過ChangeTracker API獲取和更改:

   context.Entry(myBlog).Property("LastUpdated").CurrentValue = DateTime.Now;

  

  下面講第一個功能:當數據庫中某些字段不想映射到實體類上公開的屬性時,隱藏屬性非常有用

  1.1 配置隱藏屬性

    不能通過數據註釋來創建隱藏屬性,只能通過 Fluent API 來創建, Blog實體中沒有映射LastUpdated公開屬性,但創建了隱藏屬性。

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

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity
<Blog>().Property<DateTime>("LastUpdated"); } } public class Blog { public int BlogId { get; set; } public string Url { get; set; } }

    

  1.2 設置隱藏屬性值

    在新增時blog一條數據時,通過ChangeTracker API可以為隱藏屬性LastUpdated設置時間值,提交到數據庫表中。

          [HttpPost]
        public
async Task<IActionResult> Create([Bind("Url")] Blog blog) { if (ModelState.IsValid) { //設置隱藏屬性的值 BloggingContext.Entry(blog).Property("LastUpdated").CurrentValue = DateTime.Now; BloggingContext.Add<Blog>(blog); await BloggingContext.SaveChangesAsync(); } return View(); }

      技術分享圖片

    

  1.3 讀取blog表數據

    可以通過 LINQ 查詢中引用隱藏屬性EF.Property靜態方法,通過隱藏屬性LastUpdated排序,讀取blog集合數據。

    var blogs = context.Blogs.OrderBy(b => EF.Property<DateTime>(b, "LastUpdated"));

二.約定

  下面講第二個功能,隱藏屬性通常用於外鍵屬性。當二個實體存在主從關系,但在依賴實體類中找不到外鍵屬性時,默認是通過"約定"來創建隱藏外鍵屬性的。隱藏外鍵屬性將被命名為<navigation property name><principal key property name>。以下面的示例來說:post依賴實體中包含了隱藏的外鍵屬性 “BlogId ”。

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; }
}

  下面簡單測試下,通過初例化一個的Post依賴實體,查看該實例中是否包含了BlogId 外鍵隱藏屬性,通過ChangeTracker API來獲取,使用斷點查看該BlogId 隱藏屬性確實存在,只是在Post實體上是非公開的外鍵屬性:

   public void OnGet()
        {
            object obj = _bloggingContext.Entry(new Post()).Property("BlogId").CurrentValue;
        }
_bloggingContext.Entry(new Post()).Property("BlogId")
{Microsoft.EntityFrameworkCore.ChangeTracking.PropertyEntry}
    CurrentValue: null
    EntityEntry: {Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalMixedEntityEntry}
    InternalEntry: {Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalMixedEntityEntry}
    IsModified: false
    IsTemporary: false
    Metadata (Microsoft.EntityFrameworkCore.ChangeTracking.MemberEntry): {Property: Post.BlogId (no field, Nullable<int>) Shadow FK Index 1 1 1 0 1}
    Metadata: {Property: Post.BlogId (no field, Nullable<int>) Shadow FK Index 1 1 1 0 1}
    OriginalValue: null

  

參考文獻:

    官方文檔:EF 隱藏屬性

asp.net core系列 25 EF模型配置(隱藏屬性)