站点图标 江湖人士

现有数据库如何使用Entity Framework Core

现有数据库如何使用Entity Framework Core

在本篇文章,您将学习现有数据库如何使用Entity Framework Core创建上下文和实体类。为现有数据库创建实体和上下文类称为(DB First)数据库先行方法。

EF Core不支持DB模型和向导的可视化设计器来创建类似于EF 6的实体和上下文类。因此,我们需要使用该Scaffold-DbContext命令进行逆向工程。此逆向工程命令DbContext基于现有数据库的模式创建实体和上下文类(通过派生)。

现有数据库如何使用Entity Framework Core

让我们为下面显示的本地MS SQL Server中的以下SchoolDB数据库创建实体和上下文类。

现有数据库如何使用Entity Framework Core

Scaffold-DbContext命令

用于Scaffold-DbContext基于现有数据库创建模型。可以使用程序包管理器控制台中的Scaffold-DbContext指定以下参数:

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

在Visual Studio中,选择菜单:(工具)Tools – > (NuGet包管理器)NuGet Package Manger – > (程序包管理器控制台)Package Manger Console并运行以下命令:

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

在上面的命令中,第一个参数是一个连接字符串,它包括三个部分:DB Server,数据库名称和安全信息。这里Server=.SQLExpress;指的是本地SQLEXPRESS数据库服务器。Database=SchoolDB;指定我们要为其创建类的数据库名称“SchoolDB”。Trusted_Connection=True;指定Windows身份验证。它将使用Windows凭据连接到SQL Server。第二个参数是提供者名称。我们使用SQL Server的提供程序,所以它是Microsoft.EntityFrameworkCore.SqlServer。该-OutputDir参数指定了我们想要生成所有类的目录,在本例中是Models文件夹。

使用以下命令获取有关Scaffold-DbContext命令的详细帮助:

PM> get-help scaffold-dbcontext –detailed

上面的Scaffold-DbContext命令使用Fluent API配置为Models文件夹中的所有实体创建SchoolDB数据库和上下文类中每个表的实体类(通过派生DbContext)。

现有数据库如何使用Entity Framework Core

以下是表的生成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或Views创建实体类。

DotNet CLI

如果使用dotnet命令行界面执行EF Core命令,则打开命令提示符并导航到根文件夹并执行以下 dotnet ef dbcontext scaffold命令:

> dotnet ef dbcontext scaffold "Server=.SQLEXPRESS;Database=SchoolDB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Models

因此,您可以为现有数据库创建EF Core模型。

注意:创建模型后,每当更改模型时都必须使用“迁移”命令,以使数据库与模型保持同步。

退出移动版