• ASP.NET CORE 使用 EF CORE访问数据库


    asp.net core通过ef core来访问数据库,这里用的是代码优先,通过迁移来同步数据库与模型。

    环境:vs2017,win10,asp.net core 2.1

    一、从建立asp.net core web项目开始                                                                                

    1、通过vs2017建立一个asp.net core web应用程序

    2、在models文件夹下面创建一个student类,这个类用作数据模型,表示的是数据库里面的student表 

    public class Student
        {
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            public Guid ID { set; get; }
            [Required]
            [MaxLength(30)]
            public string Name { set; get; }
            public int Age { set; get; }
            public byte Sex { set; get; }
            public string Remark { set; get; }
    
    
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public DateTime CreateDate { set; get; }
            [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
            public DateTime LastUpdate { set; get; }
        }

     关于表里面的特性说明这里暂时不管,等创建了数据库后再来说明。

    3、创建数据库上下文

    在项目中建立一个Data文件夹,创建一个类SqlServerContext

    public class SqlServerContext : DbContext
        {
            public SqlServerContext(DbContextOptions<SqlServerContext> options)
               : base(options)
            {
            }
            public DbSet<Student> Students { get; set; }
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Student>().ToTable("Student");
            }
        }

    在 Entity Framework 中,实体集通常与数据表相对应,具体实体与表中的行相对应。当数据库创建完成后, EF 创建一系列数据表,表名默认和 DbSet 属性名相同。但可以在OnModelCreating方法中指定表名。

    4、注册数据库上下文

    打开 Startup.cs,在ConfigureServices方法中添加如下代码

    services.AddDbContext<SqlServerContext>(options =>
                        options.UseSqlServer(Configuration.GetConnectionString("SqlServerContext")));

    SqlServerContext是数据库字符串的名称。打开appsettings.json 文件,并如以下示例所示添加连接字符串。

    "ConnectionStrings": {
        "SqlServerContext": "Server=(localdb)\ProjectsV84;Database=TestDB1;Trusted_Connection=True;MultipleActiveResultSets=true"
      }

    这里连接的是本地数据库,数据库的验证方式是windows验证。

    5、迁移

    通过命令行接口 (CLI)执行迁移命令来实现迁移,在此之前,需要按照适用于命令行接口 (CLI) 的 EF 工具。 注意: 必须通过编辑 .csproj 文件来安装此包;不能使用 install-package 命令或包管理器 GUI。

    若要编辑 .csproj 文件,可右键单击解决方案资源管理器中的项目名称,然后选择“编辑EFCoreDB.csproj”,在ItemGroup里面添加如下代码

        <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
        <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />

    在项目所在的文件夹下打开cmd窗口,执行命令:dotnet ef migrations add CreateDB

    命令执行成功的话,会在项目中添加一个文件夹Migrations

    这里面的两个文件就是EF如何创建数据库的,一般来说不需要手动去修改这两个文件。

    这时候,数据库里面还没有相应的数据库和表

    在cmd中执行命令dotnet ef database update,成功执行后,就可以在数据库里面看到创建的数据库和表了

    6、分析

    现在来看看student表的列和模型student的关系

    系统默认ID是主键,这是一种约定,当然也可以在模型student的ID属性上用 [Key]来修饰,这时候ID可以是其他的名称。具体有关模型创建的信息,请参考创建并配置模型

    模型中,ID的类型是guid,在数据库里面就对应类型uniqueidentifier,[DatabaseGenerated(DatabaseGeneratedOption.None)]特性表示ID列不需要数据库自动添加值。

    Name和Remark都是string类型,remark没有任何修饰,所以数据库中的类型就是nvarchar(max),且可以为空。

    7、步骤优化

    上面的的6个步骤中,第3,4两步可以不用手动添加。可以通过新搭建基架的项目命令来完成。

    先完成上面的1,2两个步骤,然后在Controllers文件夹上右键==》添加==》新搭建基架的项目

    在模型类中选择第二步添加的模型student,数据上下文类中,点击后面的+号,将名称改为sqlserver,其他的默认就行,最后点击添加。系统会自动的创建数据上下文,并且还帮你注册了,除此之外,还添加了students控制器和相应的视图,对于控制器和视图可以保留,也可以删掉。剩下的需要修改一下配置文件中数据库的连接字符串,然后接着第五步继续就可以了。

    二、当模型修改或者添加新的模型后

    1、修改模型student,添加一个学号字段code;添加模型course,每个学生可以报多个课程,每个课程可以有多个学生报名,因此student和course是多对多的关系,需要一个中间表来关联,所以添加模型Enrollment。修改后的模型如下:

       public class Student
        {
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            public Guid ID { set; get; }
            [Required]
            [MaxLength(30)]
            public string Name { set; get; }
            [Required]
            [MaxLength(30)]
            public string Code { set; get; }
            public int Age { set; get; }
            public byte Sex { set; get; }
            public string Remark { set; get; }
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public DateTime CreateDate { set; get; }
            [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
            public DateTime LastUpdate { set; get; }
            public ICollection<Enrollment> Enrollments { get; set; }
        }
    
        public class Enrollment
        {
         public int EnrollmentID { get; set; }
    public int CourseID { get; set; } public Guid StudentID { get; set; } public Grade? Grade { get; set; } public Course Course { get; set; } public Student Student { get; set; } } public enum Grade { A, B, C, D, F } public class Course { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } public ICollection<Enrollment> Enrollments { get; set; } }

    修改数据上下文

     public class SqlServerContext : DbContext
        {
            public SqlServerContext(DbContextOptions<SqlServerContext> options)
               : base(options)
            {
            }
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Student>().ToTable("Student");
                modelBuilder.Entity<Course>().ToTable("Course");
                modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
    
            }
            public DbSet<Student> Students { get; set; }
            public DbSet<Enrollment> Enrollments { get; set; }
            public DbSet<Course> Courses { get; set; }
    
        }

    2、迁移

    执行这个命令后,在Migrations文件夹中添加了20190329030918_AddTable.cs文件,里面的内容就是关于模型的修改的一些代码

    继续执行命令dotnet ef database update

    完事后,数据库中表已经正常添加了

    通过上面的方式,在student表中添加了列code,新建的表Enrollment中有主键和外键。当然也可以不用设置外键,直接将表Enrollment的CourseID和StudentID设置为复合主键。这样的话,模型student中就不需要导航属性StudentID(Course,Enrollment中也是如此)。同时数据上下文中需要指定Enrollment表的复合主键:

    modelBuilder.Entity<Enrollment>().ToTable("Enrollment").HasKey(c=>new { c.StudentID,c.CourseID});

    这样一来,Enrollment中的EnrollmentID也要去掉。设置复合主键只能是在数据上下文中设置

    三、为数据库添加初始数据

    在数据库中,有些表是有初始数据的,可以通过sql语句导入,在这里通过程序来实现吧

    打开Program.cs文件,修改后:

    public class Program
        {
            public static void Main(string[] args)
            {
                var host = CreateWebHostBuilder(args).Build();
                using (var scope = host.Services.CreateScope())
                {
                    var services = scope.ServiceProvider;
                    try
                    {
                        var context = services.GetRequiredService<SqlServerContext>();
                        Initialize(context);
                    }
                    catch (Exception ex)
                    {
                        var logger = services.GetRequiredService<ILogger<Program>>();
                        logger.LogError(ex, "An error occurred while seeding the database.");
                    }
                }
    
    
                host.Run();
            }
    
            public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .UseStartup<Startup>();
    
            private static void Initialize(SqlServerContext context)
            {
                if (!context.Courses.Any())
                {
                    var courses = new Course[]
                    {
                    new Course{CourseID=1050,Title="数学",Credits=3},
                    new Course{CourseID=4022,Title="语文",Credits=3},
                    new Course{CourseID=4041,Title="英语",Credits=3},
                    new Course{CourseID=1045,Title="化学",Credits=4},
                    new Course{CourseID=3141,Title="生物",Credits=4},
                    new Course{CourseID=2021,Title="物理",Credits=3},
                    new Course{CourseID=2042,Title="体育",Credits=4}
                    };
                        foreach (Course c in courses)
                        {
                            context.Courses.Add(c);
                        }
                        context.SaveChanges();
                }
    
            }
    
        }

    运行程序,数据就会添加到数据库了。

    四、数据库表里面有数据的情况下修改表结构

     这里的修改肯定是合理的修改,不能说你将字符串的列改成了数字的列。这里试验一下添加新的列,不能为空的

    1、在course模型中,添加一个非空的字段

    2、迁移

    执行完迁移的第一个命令后,打开系统添加的文件,找到Up方法

    可以看到up方法里面只有影响修改的部分,要设置一个非空列的初始值,就需要在这里改代码了,改好了之后执行迁移的第二个命令。查询数据库,表结构已经更改,而且里面的数据也没有丢失。

     

     关于EF CORE的应用的基本介绍就到这里,更深入的学习还是参考微软官方文档

        

  • 相关阅读:
    scrapy安装教程
    【bzoj4200】[Noi2015]小园丁与老司机 STL-map+dp+有上下界最小流
    【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分
    【bzoj4198】[Noi2015]荷马史诗 贪心+堆
    【bzoj2989】数列 KD-tree+旋转坐标系
    【bzoj4212】神牛的养成计划 Trie树+可持久化Trie树
    【bzoj4242】水壶 BFS+最小生成树+倍增LCA
    【bzoj4238】电压 DFS树
    【bzoj4240】有趣的家庭菜园 贪心+树状数组
    【bzoj4237】稻草人 分治+单调栈+二分
  • 原文地址:https://www.cnblogs.com/jin-/p/10619651.html
Copyright © 2020-2023  润新知