.NET Core金沙js娱乐场官方网站 3增加了对使用WPF和Windows,Framework的一个轻量级

Entity Framework Core,Framework,微软也在.NET Core 3中支持Entity Framework,Forms框架以及现代控件构建Windows桌面应用程序的支持,Entity Framework,Framework的一个轻量级,Framework Core是一个支持跨平台的全新版本,跨平台的特性是EF6.x无法替代的优势

目前,Entity Framework Core
3.1 和 Entity
Framework
6.4 已正式发布。

IT之家1月2日消息在微软Connect(); 2018大会上,微软宣布推出.NET Core
3预览版,使用Visual Studio 2019预览版、Visual Studio for Mac以及Visual
Studio Code均可开发.NET Core 3应用程序。.NET Core
3的面世,是一次重大更新。

实体框架核心(EF Core)是Entity
Framework的一个轻量级,可扩展和跨平台版本。 10月25日,Entity Framework
Core 1.1 Preview 1发布了。

前言

这是.Net Core
2.0生态生态介绍的最后一篇,EF一直是我喜欢的一个ORM框架,随着版本升级EF也发展到EF6.x,Entity
Framework Core是一个支持跨平台的全新版本,可以用三个词来概况EF
Core的特点:轻量级、可扩展、跨平台。跨平台的特性是EF6.x无法替代的优势,也许会成为你在项目中技术选型的原因之一。

对于.NET Core 2.0的发布介绍,围绕2.0的架构体系,本系列相关文章:

  1. .Net Core 2.0 生态(1).NET Standard 2.0
    特性介绍和使用指南(已发布)
  2. .Net Core 2.0 生态(2).NET Core 2.0
    特性介绍和使用指南(已发布)
  3. .Net Core 2.0 生态(3)ASP.NET Core 2.0
    特性介绍和使用指南(已发布)
  4. .Net Core 2.0 生态(4)Entity Framework Core 2.0
    特性介绍和使用指南(已发布)

EF Core 3.1的获取方式

微软官方带来了关于.NET Core 3的新功能抢鲜体验介绍:

升级到Entity Framework Core 1.1 Preview 1

如果您使用由EF团队(SQL
Server,SQLite和InMemory)提供的数据库提供程序之一,则只需升级提供程序包。

PM> Update-Package Microsoft.EntityFrameworkCore.SqlServer –Pre
如果您使用的是第三方数据库提供程序,请检查它们是否已发布依赖于1.1.0-preview1-final的更新。 如果他们有,那么只是升级到新版本。 如果没有,那么你应该只能升级它们依赖的EF Core关系组件。 1.1中的大部分新功能不需要更改数据库提供程序。 EF开发组做了一些测试,以确保依赖于1.0的数据库提供程序继续使用1.1预览1,但这个测试还不详尽。

 
PM> Update-Package Microsoft.EntityFrameworkCore.Relational –Pre

获取和使用

在命令行工具安装NuGet包,比如:安装SQL Server EF
Core提供程序,并指定版本为2.0.0

$ dotnet add package Microsoft.EntityFrameworkCore.SqlServer -V 2.0.0

在VS2017中使用包管理器控制台安装

PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 2.0.0

在ASP.NET Core 2.0默认项目包含支持EF Core 2.0的SQL Server, SQLite, 和
in-memory数据库提供程序,创建项目无需额外添加。

查看在不同平台上使用EF
Core指南,查看更多安装和升级细节,进入帮助文档。

EF Core 3.1 作为一组 NuGet 软件包专门分发。例如,要将 SQL Server
提供程序添加到您的项目中,可以使用 dotnet 工具使用以下命令:

.NET Framework 4.8

升级tooling packages

如果你使用的工具包,那么一定要升级。
请注意,工具版本化为1.0.0-preview3-final,因为工具尚未达到其初始稳定版本(在.NET
Core,ASP.NET Core和EF Core上的工具都是如此)。

PM> Update-Package Microsoft.EntityFrameworkCore.Tools –Pre
如果您使用的是ASP.NET Core,那么您需要更新project.json的tools部分以使用新的Microsoft.EntityFrameworkCore.Tools.DotNet包。 随着.NET CLI工具的设计的进行,我们必须将dotnet ef工具分离到这个单独的包中。
"tools": {
  "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-preview3-final"
},

新特性

以下是最显著的新特性:

  • 使用.NET Standard 2.0目标框架:这使得EF Core
    2.0可支持多种.NET平台实现和应用程序类型,查看平台支持列表。

  • LINQ解析改进:EF Core
    2.0中的查询更加高效,适应多种场景。举个例子,增加了翻译成SQL语句模式的数量限制,避免了在以前版本中因为客户端计算导致多重查询的问题。(优化了客户端计算性能)

  • Like查询支持:LINQ查询可以使用EF.Functions.Like(),最终解析为SQL中的like语句,在必要的时候会进行内存计算,举个例子,下面的查询:

    var customers =
    from c in context.Customers
    where EF.Functions.Like(c.Name, “a%”);
    select c;

解析成SQL语句:

  SELECT [c].[Id], [c].[Name]
  FROM [Customers] AS [c]
  WHERE [c].[Name] LIKE N'a%';

和SQL中like语句一样使用通配符。

  • 实体包含关系和表拆分:可以通过属性关联建立实体之间的包含关系,这个特性和EF6中的复合类型类似,只需要定义一个导航属性。实体包含关系定义与表拆分结合使用,可以将两个实体自动映射为单张表,参看下面的示例:

    public class Customer
    {
        public int Id { get; set; }
        public string Name {get; set;}
        public PhysicalAddress Address { get; set; }
    }
    
    public class PhysicalAddress
    {
        public string StreetAddress { get; set; }
        public Location Location { get; set; }
    }
    
    ...
    
    modelBuilder.Entity<Customer>()
        .OwnsOne(c => c.Address);
    
  • 全局查询过滤器:在DbContext中为实体定义查询过滤器,下面代码在OnModelCreating方法中定义:

    modelBuilder.Entity<Post>()
    .HasQueryFilter(p => !p.IsDeleted);
    

下面的查询只会返回未被标记为删除的结果:

  var blog = context.Blogs
  .Include(b => b.Posts)
  .FirstOrDefault(b => b.Id == id);

这个特性在特殊的业务场景下将有大用处,比如多租户中数据过滤实现。

  • DbContext Pooling(池):这项特性能够显著提升Asp.net
    Core应用程序的性能,通过在服务注册DbContext类型时启用,使用预先创建的实例池,避免为每个请求创建新实例:

    services.AddDbContextPool(
    options => options.UseSqlServer(connectionString));

    这是一个最佳实践,推荐使用!

  • SQL方法支持字符串插值:下面的SQL语句使用了C#中字符串插值语法,简化参数化查询:

    var city = "Redmond";
    
    using (var context = CreateContext())
    {
        context.Customers.FromSql($@"
            SELECT *
            FROM Customers
            WHERE City = {city}");
    }
    

以上代码转换为SQL语句会创建一个名为@p0的参数,值为Redmond,生成如下SQL语句:

    SELECT *
    FROM Customers
    WHERE City = @p0
  • 更多特性:如:显式编译查询、自包含实体配置、数据库标准函数映射。还修复了许多Bug。详细内容参考:新功能
dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 3.1.0

Microsoft Connect(); 2018上,微软宣布将于明年发布.NET Framework
4.8。随着支持4K和8K分辨率的显示器的普及,微软正在对WPF和Windows
Forms升级,以对高DPI提供更好的支持。目前,许多.NET
Core应用都是基于旧版本Internet Explorer和Windows Media
Player的浏览器和媒体控件。微软正在添加使用Windows
10中最新浏览器和媒体播放器的新控件,并支持最新标准。WPF和Windows
Forms应用程序将可以通过XAML Islands访问Windows UI
XAML库,以获得现代化的外观和触摸支持。Visual Studio 2019基于.NET
Framework并应用了许多此类功能。

什么是Entity Framework Core 1.1 Preview 1

1.1版本专注于解决阻止人们采用EF Core的问题。
这包括修复错误并添加一些尚未在EF Core中实现的关键功能。
虽然EF开发组在这方面取得了一些良好的进展,但是,EF
Core仍然不会是每个人的正确选择。 有关实现的更多详细信息,请参阅下面的EF
Core和EF6.x比较。

项目升级和核心API变化

  1. 将项目.NET平台设置为支持.NET Standard 2.0的平台
  2. 使用支持2.0的数据库提供程序
  3. 更新EF Core引用包(包括运行时和工具)到2.0
  4. 必要的时候对代码进行修改,具体参看核心变化

在2.0版本中,部分API和操作有较大改进,有部分改进需要修改现有程序代码,对于大多数应用程序来说,影响不大,大多数情况下,只需要重新编译和最少的修改来替换过时的API。

将面向较早版本的 ASP.NET Core 的应用程序升级到 3.1 时,您可能还必须添加
EF Core 程序包作为显式依赖项。

Windows桌面进入.NET Core

EF Core和EF6.x比较

有两个版本的Entity Framework,Entity Framework Core和Entity Framework
6.x.

获取应用程序服务新方式

注:EF
Core在设计时的操作比如生成数据迁移代码,更新数据库,需要访问应用程序服务。设计时工具和应用程序存在调用关系。

推荐将ASP.NET Core Web应用程序更新到2.0,在ASP.NET Core
2.0在启动类之外初始化配置。在之前的版本EF
Core尝试执行Startup.ConfigureServices,直接访问应用程序的服务提供者,使用EF
Core的应用程序通常从配置文件中访问连接字符串,所以单靠Startup已经不能满足获取连接字符串的需要。

更新ASP.NET Core 1.x到2.0,当使用了EF Core工具,会收到如下错误提示:

No parameterless constructor was found on ‘ApplicationContext’. Either
add a parameterless constructor to ‘ApplicationContext’ or add an
implementation of ‘IDesignTimeDbContextFactory’ in the same assembly
as ‘ApplicationContext’

在ASP.NET Core
2.0默认模板中新增设计时支持,静态方法Program.BuildWebHost允许EF
Core在设计时访问应用程序服务提供者,如果升级ASP.NET Core
1.x应用程序,同时升级Program

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace AspNetCoreDotNetCore2._0App
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

注:如果没有ASP.NET Core
2.0应用程序没有更改Program启动方式,依然可以使用实现IDesignTimeDbContextFactory<ApplicationContext>接口方式提供EF
Core 2.0设计时支持,不推荐这么做。

从 3.0 开始到 3.1 继续,.NET Core SDK 中不再包含 dotnet ef
命令行工具。在执行 EF Core
迁移或脚手架命令之前,您必须将此软件包作为全局或本地工具安装。要将 3.1.0
工具的最终版本安装为全局工具,请使用以下命令:

.NET Core的前两个版本主要侧重于支持Web应用、Web
API、IoT和控制台应用程序。.NET Core 3增加了对使用WPF和Windows
Forms框架以及现代控件构建Windows桌面应用程序的支持,并能够实现XAML
Islands从Windows UI XAML库构建Fluent样式。目前有许多桌面应用使用Entity
Framework进行数据访问,因此,微软也在.NET Core 3中支持Entity Framework
6。这些框架能够让构建Windows桌面应用的开发人员充分利用.NET
Core中的新功能,例如并行部署、自包含应用、CoreFX的最新改进等等。

Entity Framework 6.x

Entity Framework
6.x(EF6.x)是一种经过试验和测试的数据访问技术,具有多年的功能和稳定性。
它首次在2008年发布,作为.NET Framework 3.5 SP1和Visual Studio 2008
SP1的一部分。 从EF4.1版本开始,它作为EntityFramework NuGet包发运 –
目前是NuGet.org上最受欢迎的包。

EF6.x继续是一个受支持的产品,并将继续进行错误修复和小的改进。

IDbContextFactory改名

为了支持不同的应用模式,在设计时提供对DbContext更多自定义控制,在以前的版本提供接口IDbContextFactory<TContext>,EF
Core工具在设计时,会发现应用程序中该接口的实现并使用它来创建DbContext对象。

这个接口因为具有通用性的名称,容易误导开发者使用来处理需要重新创建DbContext的开发场景,当在设计时EF
Core工具使用它时因为没有考虑到设计时的特殊环境可以导致Update-Databasedotnet ef database update命令执行失败。

基于以上的原因,为了更精准的表达该接口的作用,我们将其改名为IDesignTimeDbContextFactory<TContext>,在2.0中IDbContextFactory<TContext>仍然存在,但是已经标记为过时了。

dotnet tool install --global dotnet-ef --version 3.1.0

开源的WPF、Windows Forms和WinUI

Entity Framework Core

实体框架核心(EF Core)是Entity
Framework的一个轻量级,可扩展和跨平台版本。 与EF6.x相比,EF
Core引入了许多改进和新功能。 同时,EF Core 是一个新的代码基础

EF Core保留了来自EF6.x的开发者体验,大多数顶级API也保持不变,因此EF
Core对使用EF6.x的用户会感到非常熟悉。 同时,EF
Core构建了一套全新的核心组件。 这意味着EF
Core不会自动继承EF6.x的所有功能。
其中一些功能将在未来版本中显示(例如延迟加载和连接弹性),其他较不常用的功能将不会在EF
Core中实现。

新的,可扩展的和轻量级核心还允许我们在EF核心中添加一些在EF6.x中不能实现的特性(例如在LINQ查询中的备用密钥和混合客户端/数据库评估)。

DbContextFactoryOptions移除

因为ASP.NET
2.0的升级,我们发现在接口IDesignTimeDbContextFactory<TContext>不在需要DbContextFactoryOptions
下面是你应该使用的替代方案。

  • DbContextFactoryOptions.ApplicationBasePath
    使用AppContext.BaseDirectory代替
  • DbContextFactoryOptions.ContentRootPath
    使用Directory.GetCurrentDirectory()代替
  • DbContextFactoryOptions.EnvironmentName
    使用Environment.GetEnvironmentVariable(“ASPNETCORE_ENVIRONMENT”)代替

可以将新版本的 dotnet ef 与使用 EF Core
运行时的较旧版本的项目一起使用。但是,该工具的较旧版本不适用于 EF Core
3.1。

大会上宣布WPF、Windows Forms和WinUI开源,即三个主要的Windows
UX技术都将开源。这是史无前例的创举,整个社区都将公开的看到WPF、Windows
Forms和WinUI的进展,第一批代码将在GitHub上发布,未来几个月还会发布更多代码,这让全球开发者无比惊喜。

改进LINQ翻译

在1.1版本中,EF研发团队在改进EF Core LINQ提供程序方面取得了良好的进展。
这使得更多的查询能够成功执行,在数据库(而不是内存)中评估更多的逻辑。

EF Core 2.0需要2.0数据库提供程序

对于EF Core
2.0,我们已经对数据库提供程序的工作进行了许多简化和改进。1.0.x和1.1.x提供程序已经不能在EF
Core 2.0下工作。

由EF团队开发的SQL
Server和SQLite数据库提供程序,2.0版本将在2.0版本中提供。其他数据库提供程序也已经升级到2.0版本:

  • SQL
    Compact
  • PostgreSQL
  • MySQL

EF Core 3.1的新增功能

WPF和Windows Forms

DbSet.Find

DbSet.Find(…)是一个存在于EF6.x中的API,并且是EF
Core的更常见的请求之一。 它允许您根据主键值轻松查询实体。
如果实体已经加载到上下文中,则返回它而不查询数据库。

using (var db = new BloggingContext())
{
    var blog = db.Blogs.Find(1);
}

日志记录和诊断事件更改

注意:这些更改不会影响大多数的应用程序代码。

发送给ILogger的消息的事件ID在2.0中发生了变化。现在在EF
Core中事件ID是全局唯一的。这些消息现在也遵循了结构化日志的标准模式,例如,MVC。

Logger类别也发生了变化,类别可通过DbLoggerCategory访问。

DiagnosticSource事件现在使用与对应ILogger消息相同的时间ID名称,事件ID、有效负载类型和类别进行了统一。

ID从Microsoft.EntityFrameworkCore.Infraestructure命名空间移到Microsoft.EntityFrameworkCore.Diagnostics

  • 据悉,EF Core 3.1 的主要目标是完善在 EF Core 3.0
    中提供的功能和方案。EF Core 3.1
    将是一个长期支持(LTS)版本,至少支持 3 年。EF Core 3.1 重新引入了对
    .NET Standard 2.0 的支持,而不是像 EF Core 3.0 那样要求 .NET
    Standard 2.1 。这意味着 EF Core 3.1 将在支持该标准的 .NET Framework
    版本上运行。
  • 此外,该版本还修复了 150
    多个问题,但没有要宣布的主要新功能。

WPF和Windows Forms现在可以与.NET
Core一起使用。它们出现在一个名为“Windows桌面”的新组件中,该组件是Windows版本的SDK的一部分。

映射到字段(Mapping to fields)

API中的新的HasField(…)方法允许您为属性配置备用字段。
这是最常见的做法是当一个属性没有setter。

public class BloggingContext : DbContext
{
    ...

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity()
.Property(b => b.Url)
.HasField(“_theUrl”);
}
}

默认情况下,EF将在查询期间构造实体的实例时使用该字段,或者当它无法使用该属性时(即,它需要设置值,但没有属性设置器)。 您可以通过新的UsePropertyAccessMode(...)API更改。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Url)
        .HasField("_theUrl")
        .UsePropertyAccessMode(PropertyAccessMode.Field);
}

您还可以在模型中创建在实体类中没有相应属性的属性,但使用字段将数据存储在实体中。
这与“阴影属性”(下面介绍,距离此处12cm)不同,数据存储在更改跟踪器中。
如果实体类使用方法来获取/设置值,则通常使用此方法。

您可以在属性(…)API中给EF字段的名称。
如果没有具有给定名称的属性,则EF将寻找一个字段。

public class BloggingContext : DbContext
{
    ...

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity()
.Property(“_theUrl”);
}
}

您还可以选择为该属性指定名称,而不是字段名称。 然后在创建模型时使用此名称,最明显的是它将用于映射到数据库中的列名称。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property<string>("Url")
        .HasField("_theUrl");
}
您可以使用EF.Property(...)方法在LINQ查询中引用这些属性。
var blogs = db.Blogs
    .OrderBy(b => EF.Property<string>(b, "Url"))
    .ToList();
 

EF Core元数据关系API变化

EF Core
2.0为不同的提供程序创建一个不同的IModel,这通常对应用程序是透明的,从而简化了底层元数据API,使得任何对公共关系的元数据都可以通过调用来实现,对比如下代码,在1.1.x中代码:

var tableName = context.Model.FindEntityType(typeof(User)).SqlServer().TableName;

现在可以这么写

var tableName = context.Model.FindEntityType(typeof(User)).Relational().TableName;

更具通用性。

在比如使用方法ForSqlServerToTable,现在可以使用更加通用的代码来实现

modelBuilder.Entity<User>().ToTable(
Database.IsSqlServer() ? "SqlServerName" : "OtherName");

请注意,此更改仅适用于为所有关系提供程序定义的API/元数据。当只针对单个提供者时,API和元数据仍然是相同的。举个例子,聚集索引是SQL
Server特有的,所以ForSqlServerIsClustered.SqlServer().IsClustered()必须使用。

EF 6.4的新增功能

开发者可以从命令行创建针对WPF和Windows Forms的新.NET Core项目。如:

阴影属性(Entity Framework Core)

阴影属性是实体类中不存在的属性。
这些属性的值和状态完全保留在更改跟踪器中

可以通过ChangeTracker API获取和更改阴影属性值。

context.Entry(myBlog).Property("LastUpdated").CurrentValue = DateTime.Now;
阴影属性可以通过EF.Property静态方法在LINQ查询中引用。
var blogs = context.Blogs
    .OrderBy(b => EF.Property<DateTime>(b, "LastUpdated"));

不要控制EF服务提供程序

EF Core使用内置IServiceProvider在框架内部实现,应用程序应该允许EF
Core创建和管理这个提供程序。强烈建议删除所有UseInternalServiceProvider的调用,AddEntityFrameworkAddEntityFrameworkSqlServer不需要通过应用程序代码调用,建议移除。AddDbContext的使用方式和以前一样。