Entity Framework Core系列教程-3爲現有數據庫生成實體模型

在Entity Framework Core中爲現有數據庫創建模型

在這裏,您將學習如何在Entity Framework Core中爲現有數據庫創建上下文和實體類。爲現有數據庫創建實體和上下文類稱爲Database-First方法。
EF Core不支持用於可視化設計器的DB模型和嚮導來創建類似於EF 6的實體和上下文類。因此,我們需要使用Scaffold-DbContext命令進行逆向工程。此逆向工程命令基於現有數據庫的架構創建實體和上下文類(通過派生DbContext)。
讓我們在下面顯示的本地MS SQL Server中爲以下SchoolDB數據庫創建實體和上下文類。
在這裏插入圖片描述

Scaffold-DbContext命令

使用Scaffold-DbContext基於現有數據庫創建模型。可以在Package Manager控制檯中的Scaffold-DbContext中指定以下參數:

Scaffold-DbContext [-Connection] [-Provider] [-OutputDir] [-Context] [-Schemas>] [-Tables>] 
                    [-DataAnnotations] [-Force] [-Project] [-StartupProject] [<CommonParameters>]

在Visual Studio中,選擇菜單工具-> NuGet軟件包管理器->軟件包管理器控制檯,然後運行以下命令:

Scaffold-DbContext "Server=.\SQLExpress;Database=SchoolDB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

在上面的命令中,第一個參數是一個連接字符串,它包括三個部分:
數據庫服務器, 數據庫名稱和安全信息。在這裏,Server=.\SQLExpress;指本地SQLEXPRESS數據庫服務器。
Database=SchoolDB; 指定我們要爲其創建類的數據庫名稱“ SchoolDB”。 Trusted_Connection=True; 指定Windows身份驗證。
它將使用Windows憑據連接到SQL Server。第二個參數是提供程序名稱。我們將提供程序用於SQL Server,因此它是Microsoft.EntityFrameworkCore.SqlServer。 -OutputDir參數指定我們要在其中生成所有類的目錄,在本例中爲Models文件夾。
使用以下命令可獲得有關Scaffold-DbContext命令的詳細幫助:

get-help scaffold-dbcontext –detailed

上面的Scaffold-DbContext命令使用爲Models文件夾中所有實體的Fluent API配置爲SchoolDB數據庫中的每個表創建實體類,並通過派生DbContext創建數據庫上下文類。
以下是爲Student表生成的Student實體類。:

using System;
using System.Collections.Generic;

namespace EFCoreTutorials.Models
{
    public partial class Student
    {
        public Student()
        {
            StudentCourse = new HashSet<StudentCourse>();
        }

        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int? StandardId { get; set; }

        public Standard Standard { get; set; }
        public StudentAddress StudentAddress { get; set; }
        public ICollection<StudentCourse> StudentCourse { get; set; }
    }
}

以下是SchoolDBContext類,可用於保存或檢索數據:

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace EFCoreTutorials.Models
{
    public partial class SchoolDBContext : DbContext
    {
        public virtual DbSet<Course> Course { get; set; }
        public virtual DbSet<Standard> Standard { get; set; }
        public virtual DbSet<Student> Student { get; set; }
        public virtual DbSet<StudentAddress> StudentAddress { get; set; }
        public virtual DbSet<StudentCourse> StudentCourse { get; set; }
        public virtual DbSet<Teacher> Teacher { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
                optionsBuilder.UseSqlServer(@"Server=.\SQLExpress;Database=SchoolDB;Trusted_Connection=True;");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Course>(entity =>
            {
                entity.Property(e => e.CourseName)
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.HasOne(d => d.Teacher)
                    .WithMany(p => p.Course)
                    .HasForeignKey(d => d.TeacherId)
                    .OnDelete(DeleteBehavior.Cascade)
                    .HasConstraintName("FK_Course_Teacher");
            });

            modelBuilder.Entity<Standard>(entity =>
            {
                entity.Property(e => e.Description)
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.Property(e => e.StandardName)
                    .HasMaxLength(50)
                    .IsUnicode(false);
            });

            modelBuilder.Entity<Student>(entity =>
            {
                entity.Property(e => e.StudentId).HasColumnName("StudentID");

                entity.Property(e => e.FirstName)
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.Property(e => e.LastName)
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.HasOne(d => d.Standard)
                    .WithMany(p => p.Student)
                    .HasForeignKey(d => d.StandardId)
                    .OnDelete(DeleteBehavior.Cascade)
                    .HasConstraintName("FK_Student_Standard");
            });

            modelBuilder.Entity<StudentAddress>(entity =>
            {
                entity.HasKey(e => e.StudentId);

                entity.Property(e => e.StudentId)
                    .HasColumnName("StudentID")
                    .ValueGeneratedNever();

                entity.Property(e => e.Address1)
                    .IsRequired()
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.Property(e => e.Address2)
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.Property(e => e.City)
                    .IsRequired()
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.Property(e => e.State)
                    .IsRequired()
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.HasOne(d => d.Student)
                    .WithOne(p => p.StudentAddress)
                    .HasForeignKey<StudentAddress>(d => d.StudentId)
                    .HasConstraintName("FK_StudentAddress_Student");
            });

            modelBuilder.Entity<StudentCourse>(entity =>
            {
                entity.HasKey(e => new { e.StudentId, e.CourseId });

                entity.HasOne(d => d.Course)
                    .WithMany(p => p.StudentCourse)
                    .HasForeignKey(d => d.CourseId)
                    .OnDelete(DeleteBehavior.ClientSetNull)
                    .HasConstraintName("FK_StudentCourse_Course");

                entity.HasOne(d => d.Student)
                    .WithMany(p => p.StudentCourse)
                    .HasForeignKey(d => d.StudentId)
                    .HasConstraintName("FK_StudentCourse_Student");
            });

            modelBuilder.Entity<Teacher>(entity =>
            {
                entity.Property(e => e.StandardId).HasDefaultValueSql("((0))");

                entity.Property(e => e.TeacherName)
                    .HasMaxLength(50)
                    .IsUnicode(false);

                entity.HasOne(d => d.Standard)
                    .WithMany(p => p.Teacher)
                    .HasForeignKey(d => d.StandardId)
                    .OnDelete(DeleteBehavior.Cascade)
                    .HasConstraintName("FK_Teacher_Standard");
            });
        }
    }
}

注意:EF Core僅爲表創建實體類,而不爲StoredProcedures或View創建實體類。

使用DotNet CLI

如果使用dotnet命令行界面執行EF Core命令,則打開命令提示符並導航到根文件夾,然後執行以下dotnet ef dbcontext scaffold命令:

通過本文學習,您可以使用EF Core爲現有數據庫創建EF Core模型。
注意:創建模型後,無論何時更改模型,都必須使用“遷移”命令,以使數據庫與模型保持最新。

發佈了153 篇原創文章 · 獲贊 44 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章