EF Core創建實體的Code First標准方法


針對關系型數據庫,實體之間的關系最常見的就是通過外鍵關聯的一對一、一對多和多對多的關系,新的EF Core通過注釋和Fluent API 能夠做到接近於數據庫通過DML創建模型的效果了。實際上,通過DML 最大的優勢在於,能夠定義所謂的Independent/Dependent Entity具體的那個字段作為關聯字段,而EF更多通過一種約定去描述這種關聯關系,不過通過Fluent API 能夠收工定義的操作范圍更近廣了。

 下面的這個表關系實際上描述了大部分關系型數據庫的關聯關系,能夠覆蓋大部分場景,通過這個例子去說明Code First 創建實體的標准方法。

Members 和Tasks 關系,Member是Independent Entity, Tasks是Dependent Entity,定義類如下:

namespace MemberTask.Models
{
    public partial class Members
    {
        [Key]
        public int? MemberId { get; set; }
        public string MemberName { get; set; }
        [InverseProperty("Members")]
        public List<Tasks> Tasks { get; set; }

    }
}
namespace MemberTask.Models
{
    public partial class Tasks
    {
        [Key]
        public int? TaskId { get; set; }
        public int TaskName { get; set; }
        public int MemberId { get; set; }
        [ForeignKey("MemberId")]
        public Members Members { get; set; }
        //part of many2many
        [InverseProperty("Task")]
        public List<TaskAndOaTasksR> TaskAndOaTasksRs { get; set; }
    }
}

 在這兩個實體的關系中:

先看Tasks類(紅色字體部分),通過注釋指明,MemberId 字段作為外鍵,而Members引用導航屬性,作為外鍵所關聯依賴的對象。

Members類,Tasks 列表導航屬性就是被引用對象,而注釋表明Members 就是Tasks中的引用導航屬性Members。

另外3個實體店關系為,Tasks和OaTasks是業務實體,TaskAndOaTasksRs實際上作為一個中間表,提供一種多對多的關系,這種模式實際上是作為靈活的一種實體模式,雖然有一定的空間損耗,但是無論哪種關系,或者未來需要擴展成為多對多的關系可以隨時實施。

 

OaTasks:

namespace MemberTask.Models
{
    public partial class  OaTasks
    {
        [Key]
        public int? OaTaskId { get; set; }
        public string OaTaskName { get; set; }
        [InverseProperty("OaTask")]
        public List<TaskAndOaTasksR> TaskAndOaTasksRs { get; set; }

    }
}

 TasksAndOaTasksRs:

namespace MemberTask.Models
{
    public partial class TaskAndOaTasksR
    {
        public int? TaskId { get; set; }
        [ForeignKey("TaskId")]
        public Tasks Task { get; set; }
        [ForeignKey("OaTaskId")]
        public int? OaTaskId { get; set; }
        public OaTasks OaTask { get; set; }

    }
}

TasksAndOaTasksRs在實際上使用的時候,是不需要實現TaskId查詢關聯的多個OaTaskId的,僅僅查詢TaskId & OaTaskId  的一一對應關系,因此通過引用導航屬性引用Tasks 和OaTasks。相反,Tasks 和OaTasks都有需要進行一對多關聯查詢,因此采用了列表導航屬性。

 

模型建好后,根據實際情況配置DbContext,特別是針對外鍵關聯,根據實際情況定義好OnDelete方法。

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Members>()
                .Property(b => b.MemberId).ValueGeneratedNever();
            modelBuilder.Entity<Tasks>()
                .Property(t => t.TaskId).ValueGeneratedNever();
            modelBuilder.Entity<OaTasks>()
                .Property(o => o.OaTaskId).ValueGeneratedNever();

            modelBuilder.Entity<Tasks>()
                .HasOne(m=>m.Members)
                .WithMany(t=>t.Tasks)
                .OnDelete(DeleteBehavior.Cascade);

            // below is for many2many
            modelBuilder.Entity<TaskAndOaTasksR>()
                .HasOne(t => t.Task)
                .WithMany(tt => tt.TaskAndOaTasksRs);

            modelBuilder.Entity<TaskAndOaTasksR>()
                .HasOne(t => t.OaTask)
                .WithMany(tt => tt.TaskAndOaTasksRs);

            modelBuilder.Entity<TaskAndOaTasksR>()
                .HasKey(t => new {t.TaskId, t.OaTaskId});
            
        }

 運行數據庫更新命令,實體和數據庫模型就建好了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM