本文翻译来自:https://docs.microsoft.com/en-us/ef/core/what-is-new/index

一.模型级查询过滤器(Model-level query filters)

  ef core2.0包含了一个新特性,我们叫他模型级查询过滤器(Model-level query filters)。此特性允许使用Linq查询表达式直接定义在实体类型的元数据模型上。这样的过滤器会自动应用到任何LINQ查询所涉及的那些实体类型,包括间接引用的实体类型(对象引用,导航属性)。这个特性的一些常见应用是:

  • 软删除-定义一个 IsDeleted 属性
  • 多租户-定义一个 TenantId 属性

示例代码:

 public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; } public int TenantId {get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>().HasQueryFilter(
p => !p.IsDeleted
&& p.TenantId == this.TenantId );
}
}

  我们给 Post 实体类型定义了一个模型级查询过滤器,实现了多租户和软删除。模型级过滤器将使用正确的上下文实例中的值,即执行查询的那个。

  使用  IgnoreQueryFilters() 方法在一次查询中禁用过滤器。

局限性:

  • 过滤器只能在层次结构的根实体类型上定义
  • 过滤器不允许使用导航属性进行过滤(可以根据反馈添加此功能。)

二.数据库上下文池(DbContextPool)

  这是两种可选择的性能特性之一,旨在在高并发场景中提供更好的性能支持。

  在 ef core 2.0 中,我们将自定义的DbContext类型注册到DbContextPool服务中,可让该数据库上下文类型的实例重复使用。

示例代码:

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

  如果使用这种方法,当一个控制器请求一个DbContext的实例时,首先会检查是否在DbContextPool存在该类型的实例,当一次请求结束后,任何状态的DbContext实例都会被重置,且将自身加入到DbContextPool中。

  这在概念上类似于ADO.NET提供的数据库连接池,旨在节省一些DbContext实例初始化的成本。

三.显式编译查询(Explicitly compiled queries)

  这是两种可选择的性能特性之二 。

  在以前的ef版本中,调用查询api时,可以通过自动编译并缓存编译的结果达到一次计算多次调用,有效的提高了ef的性能,显示编译查询(Explicitly compiled queries)这种机制可以绕过缓存查找的性能消耗,直接调用已经编译好的表达式,获得一个小的性能提升。

示例代码:

 // Create an explicitly compiled query
private static Func<CustomerContext, int, Customer> _customerById =
EF.CompileQuery((CustomerContext db, int id) =>
db.Customers
.Include(c => c.Address)
.Single(c => c.Id == id)); // Use the compiled query by invoking it
using (var db = new CustomerContext())
{
var customer = _customerById(db, );
}

四.在使用FromSql和ExecuteSqlCommand方法时加入参数化查询

  在使用C#6.0的特性构建SQL语句并使用FromSql和ExecuteSqlCommand方法执行SQL语句时,会自动加入使用参数化查询,防止SQL注入。

示例代码:

 var city = "London";
var contactTitle = "Sales Representative"; using (var context = CreateContext())
{
context.Set<Customer>()
.FromSql($@"
SELECT *
FROM ""Customers""
WHERE ""City"" = {city} AND
""ContactTitle"" = {contactTitle}")
.ToArray();
}

上面的代码生成的SQL:

@p0='London' (Size = )
@p1='Sales Representative' (Size = ) SELECT *
FROM ""Customers""
WHERE ""City"" = @p0
AND ""ContactTitle"" = @p1

五.Attach can track a graph of new and existing entities

  EF Core supports automatic generation of key values through a variety of mechanisms. When using this feature, a value is generated if the key property is the CLR default--usually zero or null. This means that a graph of entities can be passed to  DbContext.Attach  or  DbSet.Attach  and EF Core will mark those entities that have a key already set as Unchanged while those entities that do not have a key set will be marked as  Added . This makes it easy to attach a graph of mixed new and existing entities when using generated keys.  DbContext.Update  and  DbSet.Update  work in the same way, except that entities with a key set are marked as  Modified  instead of  Unchanged .

六.表拆分(Table splitting)

  现在可以将两个或多个实体类型映射到同一表,其中主键列将被共享,每一行对应两个或多个实体。

  要使用表拆分,必须在共享表的所有实体类型之间配置标识关系(外键属性构成主键)

示例代码:

 modelBuilder.Entity<Product>()
.HasOne(e => e.Details).WithOne(e => e.Product)
.HasForeignKey<ProductDetails>(e => e.Id);
modelBuilder.Entity<Product>().ToTable("Products");
modelBuilder.Entity<ProductDetails>().ToTable("Products");

七.Owned types

  一个owned实体类型可以与另一个owned实体类型共享相同的CLR类型。但是由于它不能被CLR类型识别,所以必须从另一个实体类型导航到它。包含定义导航的实体是所有者。当查询所有者时,默认将包含所属的类型。

  按照惯例,将为所属类型创建一个影子主键,它将通过使用表拆分映射到与所有者相同的表。

示例代码:

 modelBuilder.Entity<Order>().OwnsOne(p => p.OrderDetails, cb =>
{
cb.OwnsOne(c => c.BillingAddress);
cb.OwnsOne(c => c.ShippingAddress);
}); public class Order
{
public int Id { get; set; }
public OrderDetails OrderDetails { get; set; }
} public class OrderDetails
{
public StreetAddress BillingAddress { get; set; }
public StreetAddress ShippingAddress { get; set; }
} public class StreetAddress
{
public string Street { get; set; }
public string City { get; set; }
}

八.函数映射

  EF支持映射数据库中定义的函数,可以在LINQ查询中使用。

  需要在 DbContext 中定义一个静态方法,并且使用 DbFunctionAttribute 特性。

示例代码:

 public class BloggingContext : DbContext
{
[DbFunction]
public static int PostReadCount(int blogId)
{
throw new Exception();
}
}

  这样的方法是自动注册。一旦注册了方法,您就可以在查询的任何地方使用它。

要注意的几件事:

  • 按照惯例,在生成SQL时,该方法的名称用作函数的名称(在本例中是用户定义的函数),但可以在方法注册期间重写名称和schema。
  • 目前只支持标量函数
  • EF Core迁移将不负责创建它,您必须在数据库中创建映射函数

九.code first 实体配置

  在EF6可以通过 EntityTypeConfiguraiton 封装特定实体类型的配置代码,在EF Core2.0中,这个特性回来了(EF Core 之前的 core版本不支持)。

示例代码:

 class CustomerConfiguration : IEntityTypeConfiguration<Customer>
{
public void Configure(EntityTypeBuilder<Customer> builder)
{
builder.HasKey(c => c.AlternateKey);
builder.Property(c => c.Name).HasMaxLength();
}
} ...
// OnModelCreating
builder.ApplyConfiguration(new CustomerConfiguration());

十.Pluralization hook for DbContext Scaffolding

  EF Core 2.0 introduces a new IPluralizer service that is used to singularize entity type names and pluralize DbSet names. The default implementation is a no-op, so this is just a hook where folks can easily plug in their own pluralizer.
Here is what it looks like for a developer to hook in their own pluralizer:

 public class MyDesignTimeServices : IDesignTimeServices
{
public void ConfigureDesignTimeServices(IServiceCollection services)
{
services.AddSingleton<IPluralizer, MyPluralizer>();
}
} public class MyPluralizer : IPluralizer
{
public string Pluralize(string name)
{
return Inflector.Inflector.Pluralize(name) ?? name;
} public string Singularize(string name)
{
return Inflector.Inflector.Singularize(name) ?? name;
}
}

本人英语水平有限,如有翻译不对的地方,欢迎批评指正。

如果你觉得写的不错,请点一下的“推荐”,这是对我分享技术经验的支持,谢谢!

声明:原创博客请在转载时保留原文链接或者在文章开头加上本人博客地址,如发现错误,欢迎批评指正。凡是转载于本人的文章,不能设置打赏功能,如有特殊需求请与本人联系!

Entity Framework Core 2.0 新特性的更多相关文章

  1. .Net Core 2.0生态(4):Entity Framework Core 2.0 特性介绍和使用指南

    前言 这是.Net Core 2.0生态生态介绍的最后一篇,EF一直是我喜欢的一个ORM框架,随着版本升级EF也发展到EF6.x,Entity Framework Core是一个支持跨平台的全新版本, ...

  2. 【EF】Entity Framework Core 2.0 特性介绍和使用指南

    阅读目录 前言 获取和使用 新特性 项目升级和核心API变化 下一步计划 遗憾的地方 回到目录 前言 这是.Net Core 2.0生态生态介绍的最后一篇,EF一直是我喜欢的一个ORM框架,随着版本升 ...

  3. Entity Framework Core 2.0 中使用LIKE 操作符

    Entity Framework Core 2.0 中使用LIKE 操作符 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译 ...

  4. ASP.NET Core 1.0、ASP.NET MVC Core 1.0和Entity Framework Core 1.0

    ASP.NET 5.0 将改名为 ASP.NET Core 1.0 ASP.NET MVC 6  将改名为 ASP.NET MVC Core 1.0 Entity Framework 7.0    将 ...

  5. [转帖]2016年时的新闻:ASP.NET Core 1.0、ASP.NET MVC Core 1.0和Entity Framework Core 1.0

    ASP.NET Core 1.0.ASP.NET MVC Core 1.0和Entity Framework Core 1.0 http://www.cnblogs.com/webapi/p/5673 ...

  6. Entity Framework Core 2.0 全局查询过滤器

    不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: http://gunnarpeipman.com/2017/08/ef ...

  7. Entity Framework Core 2.0 使用代码进行自动迁移

    一.前言 我们在使用EF进行开发的时候,肯定会遇到将迁移更新到生产数据库这个问题,前面写了一篇文章介绍了Entity Framework Core 2.0的入门使用,这里面介绍了使用命令生成迁移所需的 ...

  8. ASP.Net Core项目在Mac上使用Entity Framework Core 2.0进行迁移可能会遇到的一个问题.

    在ASP.Net Core 2.0的项目里, 我使用Entity Framework Core 2.0 作为ORM. 有人习惯把数据库的连接字符串写在appSettings.json里面, 有的习惯写 ...

  9. Entity Framework Core 2.0 使用入门

    一.前言 Entity Framework(后面简称EF)作为微软家的ORM,自然而然从.NET Framework延续到了.NET Core.以前我也嫌弃EF太重而不去使用它,但是EF Core(E ...

随机推荐

  1. python3中socket套接字的编码问题解决

    一.TCP 1.tcp服务器创建 #创建服务器 from socket import * from time import ctime #导入ctime HOST = '' #任意主机 PORT = ...

  2. 16.如何做到webpack打包vue项目后,可以修改配置文件

    问题描述: 前端需要修改restful API的url,但是打包之后,配置文件找不到了,如果在npm run build 生成dist后,这个配置也被写死了,传到运行的前端服务器上后,假设某次,api ...

  3. Latex加速: TexStudio的安装和使用

    TexStudio可以加速Latex的编辑和写作,这里简单介绍一下TexStudio的安装,配置和使用.但是有一个重要的前提,TexStudio会使Latex源代码和pdf文件并排显示,比较占用桌面的 ...

  4. Python3.5学习笔记-文件操作

    在Python中,操作文件对象使用open函数来创建,下表列出了常用的操作file的函数: 序号 方法及描述 1.file.close() 关闭文件.关闭后文件不能再进行读写操作. 2.file.fl ...

  5. 微软虐我千百遍——记一次比较漫长的TFS数据库迁移

    起因 七月三日早晨刚到公司,同事就跟我讲TFS开始返回 TF30042错误,报告数据库已满.按照处理问题的第一直觉,我上bing的英文网站搜了一下,发现是部署TFS的时候使用的SQL Express限 ...

  6. EventUtil.addHandler方法

    EventUtil.addHandler: addHandler 方法,职责是分别视情况而定来使用DOM0级方法.DOM2级方法或IE方法来添加事件.   这个方法属于一个名字叫EventUtil的对 ...

  7. 安装GPU版本的tensorflow填过的那些坑!---CUDA说再见!

    那些坑,那些说不出的痛! --------回首安装的过程,真的是填了一个坑又出现了一坑的感觉.记录下了算是自己的笔记也能给需要的人提供一点帮助. 1 写在前面的话 其实在装GPU版本的tensorfl ...

  8. 妙用Outlook2003群发商业邮件

    妙用Outlook2003群发商业邮件   我们知道,如果需要在Outlook 2003中向多个对象发送邮件,那么只需要在指定收件人时用分号输入多个邮件地址或者使用抄送方式即可:假如对象较多,可以使用 ...

  9. Wireshark网络端点和会话

    如果想让网络进行正常通信,你必须至少拥有两台设备进行数据流交互.端点(endpoint)就是指网络上能够发送和接受数据的一台设备.举例来说,在TCP/IP的通信中就有两个断电:接收和发送数据系统的IP ...

  10. JS封闭函数、闭包、内置对象

    一.变量作用域 变量作用域指的是变量的作用范围,javascript中的变量分为全局变量和局部变量 1.全局变量:在函数之外定义的变量,为整个页面公用,函数的内部外部都可以访问. 2.局部变量:在函数 ...