目录

一、创建.NET Framework 4.8控制台应用

二、建立数据库

1. 在SSMS中建立数据库Blogging

2.在VS上新建数据库连接

三、安装EF程序包

四、自动生成EF模型和上下文

1.Blog.cs类的模型

2.Post.cs类的模型

3.BloggingContext.cs数据库上下文

五、编写应用程序吧


        我们都知道.NET Framework最后一个更新版本是4.8.1,而曾经支持.NET Framework的EF版本却一直更新到现在仍然在不断创新。当前主流的VS2022仍然支持.NET Framework 4.8,在.NET Framework 4.8下使用EF访问数据库,不经过一番额外的操作,想直接使用VS2022的默认安装,是不可能行得通的。幸好VS2022没有关闭在.NET Framework 4.8下使用EF访问数据库的大门。作者经过学习、整理成本文发布出来提供给有需要的人。

        本文的核心内容是:在VS2022中给.NET Framework 4.8找到并安装恰当的、支持的EF版本。只有合适的EF版本才能支持.NET Framework 4.8通过EF访问数据库。

一、创建.NET Framework 4.8控制台应用

         如何创建,此处略去。

二、建立数据库

1. 在SSMS中建立数据库Blogging

         新建数据库,新建查询,粘贴如下数据库源码,执行。

CREATE DATABASE [Blogging];
GO

USE [Blogging];
GO

CREATE TABLE [Blog] (
    [BlogId] int NOT NULL IDENTITY,
    [Url] nvarchar(max) NOT NULL,
    CONSTRAINT [PK_Blog] PRIMARY KEY ([BlogId])
);
GO

CREATE TABLE [Post] (
    [PostId] int NOT NULL IDENTITY,
    [BlogId] int NOT NULL,
    [Content] nvarchar(max),
    [Title] nvarchar(max),
    CONSTRAINT [PK_Post] PRIMARY KEY ([PostId]),
    CONSTRAINT [FK_Post_Blog_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blog] ([BlogId]) ON DELETE CASCADE
);
GO

INSERT INTO [Blog] (Url) VALUES
('http://blogs.msdn.com/dotnet'),
('http://blogs.msdn.com/webdev'),
('http://blogs.msdn.com/visualstudio')
GO

2.在VS上新建数据库连接

         在上述新建项目中,新建数据库连接,连接数据库Blogging。如何建立此连接,此处略去。

Data Source=DESKTOP-3LV13FS;Initial Catalog=Blogging;Integrated Security=True

三、安装EF程序包

         找到适合.NET Framework 4.8版本的程序包,并安装,是本文方法得以成立关键点。经过作者一番测试和查阅资料,最适合的EF版本是 3.1.32,比这再高的版本都不支持.NET Framework了。应该安装的程序包:

        NuGet\Install-Package Microsoft.EntityFrameworkCore -Version 3.1.32

        NuGet\Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 3.1.32

        NuGet\Install-Package Microsoft.EntityFrameworkCore.Design -Version 3.1.32

        NuGet\Install-Package Microsoft.EntityFrameworkCore.Tools -Version 3.1.32

         安装方法:VS2022上述项目页窗体→工具→NuGet包管理器→程序包管理器控制台→把上面蓝色的文字复制粘贴到控制台的PM>后面,回车,等待。观察右侧资源管理器,增加了一片片的引用。

         安装成功后,程序包管理器控制台没有红色警告提示信息,并有提示安装成功。也可以检查App.config查看是否安装成功。

//App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.32.0" newVersion="3.1.32.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Extensions.Configuration.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.32.0" newVersion="3.1.32.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.32.0" newVersion="3.1.32.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Extensions.Caching.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.32.0" newVersion="3.1.32.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.32.0" newVersion="3.1.32.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.32.0" newVersion="3.1.32.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Extensions.DependencyInjection" publicKeyToken="adb9793829ddae60" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.32.0" newVersion="3.1.32.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

四、自动生成EF模型和上下文

        用于访问已有数据库的EF模型和上下文是可以通过编程而自动生成的。

PM> Scaffold-DbContext "Server=DESKTOP-3LV13FS;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer
Build started...
Build succeeded.
PM> 

        右侧资源管理器自动生成与映射到了数据库的Blog.cs类的模型、Post.cs类的模型(数据库有几个列,就自动生成几个类的模型),和BloggingContext.cs数据库上下文。

C#中.NET Framework 4.8控制台应用通过EF访问已建数据库-LMLPHP

1.Blog.cs类的模型

//Blog EF模型
using System;
using System.Collections.Generic;

// Code scaffolded by EF Core assumes nullable reference types (NRTs) are not used or disabled.
// If you have enabled NRTs for your project, then un-comment the following line:
// #nullable disable

namespace _10_8
{
    public partial class Blog
    {
        public Blog()
        {
            Post = new HashSet<Post>();
        }

        public int BlogId { get; set; }
        public string Url { get; set; }

        public virtual ICollection<Post> Post { get; set; }
    }
}

2.Post.cs类的模型

//Post EF模型
using System;
using System.Collections.Generic;

// Code scaffolded by EF Core assumes nullable reference types (NRTs) are not used or disabled.
// If you have enabled NRTs for your project, then un-comment the following line:
// #nullable disable

namespace _10_8
{
    public partial class Post
    {
        public int PostId { get; set; }
        public int BlogId { get; set; }
        public string Content { get; set; }
        public string Title { get; set; }

        public virtual Blog Blog { get; set; }
    }
}

3.BloggingContext.cs数据库上下文

//DbContext类的上下文
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

// Code scaffolded by EF Core assumes nullable reference types (NRTs) are not used or disabled.
// If you have enabled NRTs for your project, then un-comment the following line:
// #nullable disable

namespace _10_8
{
    public partial class BloggingContext : DbContext
    {
        public BloggingContext()
        {
        }

        public BloggingContext(DbContextOptions<BloggingContext> options)
            : base(options)
        {
        }

        public virtual DbSet<Blog> Blog { get; set; }
        public virtual DbSet<Post> Post { 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=DESKTOP-3LV13FS;Database=Blogging;Trusted_Connection=True;");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Blog>(entity =>
            {
                entity.Property(e => e.Url).IsRequired();
            });

            modelBuilder.Entity<Post>(entity =>
            {
                entity.HasOne(d => d.Blog)
                    .WithMany(p => p.Post)
                    .HasForeignKey(d => d.BlogId);
            });

            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}

五、编写应用程序吧

        你想让这段程序干什么?现在就开始编写属于你的应用吧:通过应用程序,给Blog里增加一个新的网址,并输出到控制台。

//.NET Framework4.8下通过EF给已有数据库增加一条记录
//.NET Framework4.8下通过EF给已有数据库增加一条记录
using System;
using static System.Net.WebRequestMethods;

namespace _10_8
{
    internal class Program
    {
        static void Main(string[] args)
        {
            using (var db = new BloggingContext())
            {
                db.Blog.Add(new Blog { Url = "http://blogs.msdn.com/adonet" });
                var count = db.SaveChanges();
                Console.WriteLine("{0} records saved to database", count);

                Console.WriteLine();
                Console.WriteLine("All blogs in database:");
                foreach (var blog in db.Blog)
                {
                    Console.WriteLine(" - {0}", blog.Url);
                }
            }
        }
    }
}   //运行结果:
/*
1 records saved to database

All blogs in database:
 -http://blogs.msdn.com/dotnet
 -http://blogs.msdn.com/webdev
 -http://blogs.msdn.com/visualstudio
 -http://blogs.msdn.com/adonet
请按任意键继续. . .*/
11-14 05:26