Entity Framework Core 2.0 新特性
一.模型級(jí)查詢過(guò)濾器(Model-level query filters)
ef core2.0包含了一個(gè)新特性,我們叫他模型級(jí)查詢過(guò)濾器(Model-level query filters)。此特性允許使用Linq查詢表達(dá)式直接定義在實(shí)體類(lèi)型的元數(shù)據(jù)模型上。這樣的過(guò)濾器會(huì)自動(dòng)應(yīng)用到任何LINQ查詢所涉及的那些實(shí)體類(lèi)型,包括間接引用的實(shí)體類(lèi)型(對(duì)象引用,導(dǎo)航屬性)。這個(gè)特性的一些常見(jiàn)應(yīng)用是:
軟刪除-定義一個(gè)?IsDeleted 屬性
多租戶-定義一個(gè)?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?實(shí)體類(lèi)型定義了一個(gè)模型級(jí)查詢過(guò)濾器,實(shí)現(xiàn)了多租戶和軟刪除。模型級(jí)過(guò)濾器將使用正確的上下文實(shí)例中的值,即執(zhí)行查詢的那個(gè)。
使用??IgnoreQueryFilters()?方法在一次查詢中禁用過(guò)濾器。
局限性:
過(guò)濾器只能在層次結(jié)構(gòu)的根實(shí)體類(lèi)型上定義
過(guò)濾器不允許使用導(dǎo)航屬性進(jìn)行過(guò)濾(可以根據(jù)反饋添加此功能。)
二.數(shù)據(jù)庫(kù)上下文池(DbContextPool)
這是兩種可選擇的性能特性之一,旨在在高并發(fā)場(chǎng)景中提供更好的性能支持。
在 ef core 2.0 中,我們將自定義的DbContext類(lèi)型注冊(cè)到DbContextPool服務(wù)中,可讓該數(shù)據(jù)庫(kù)上下文類(lèi)型的實(shí)例重復(fù)使用。
示例代碼:
services.AddDbContextPool<BloggingContext>(options => options.UseSqlServer(connectionString));如果使用這種方法,當(dāng)一個(gè)控制器請(qǐng)求一個(gè)DbContext的實(shí)例時(shí),首先會(huì)檢查是否在DbContextPool存在該類(lèi)型的實(shí)例,當(dāng)一次請(qǐng)求結(jié)束后,任何狀態(tài)的DbContext實(shí)例都會(huì)被重置,且將自身加入到DbContextPool中。
這在概念上類(lèi)似于ADO.NET提供的數(shù)據(jù)庫(kù)連接池,旨在節(jié)省一些DbContext實(shí)例初始化的成本。
?
三.顯式編譯查詢(Explicitly compiled queries)
這是兩種可選擇的性能特性之二 。
在以前的ef版本中,調(diào)用查詢api時(shí),可以通過(guò)自動(dòng)編譯并緩存編譯的結(jié)果達(dá)到一次計(jì)算多次調(diào)用,有效的提高了ef的性能,顯示編譯查詢(Explicitly compiled queries)這種機(jī)制可以繞過(guò)緩存查找的性能消耗,直接調(diào)用已經(jīng)編譯好的表達(dá)式,獲得一個(gè)小的性能提升。
示例代碼:
// 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, 147);
}
四.在使用FromSql和ExecuteSqlCommand方法時(shí)加入?yún)?shù)化查詢
? 在使用C#6.0的特性構(gòu)建SQL語(yǔ)句并使用FromSql和ExecuteSqlCommand方法執(zhí)行SQL語(yǔ)句時(shí),會(huì)自動(dòng)加入使用參數(shù)化查詢,防止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:
?
五.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)
現(xiàn)在可以將兩個(gè)或多個(gè)實(shí)體類(lèi)型映射到同一表,其中主鍵列將被共享,每一行對(duì)應(yīng)兩個(gè)或多個(gè)實(shí)體。
要使用表拆分,必須在共享表的所有實(shí)體類(lèi)型之間配置標(biāo)識(shí)關(guān)系(外鍵屬性構(gòu)成主鍵)
示例代碼:
1 modelBuilder.Entity<Product>()2 .HasOne(e => e.Details).WithOne(e => e.Product)3 .HasForeignKey<ProductDetails>(e => e.Id);4 modelBuilder.Entity<Product>().ToTable("Products");5 modelBuilder.Entity<ProductDetails>().ToTable("Products");?
七.Owned types
一個(gè)owned實(shí)體類(lèi)型可以與另一個(gè)owned實(shí)體類(lèi)型共享相同的CLR類(lèi)型。但是由于它不能被CLR類(lèi)型識(shí)別,所以必須從另一個(gè)實(shí)體類(lèi)型導(dǎo)航到它。包含定義導(dǎo)航的實(shí)體是所有者。當(dāng)查詢所有者時(shí),默認(rèn)將包含所屬的類(lèi)型。
按照慣例,將為所屬類(lèi)型創(chuàng)建一個(gè)影子主鍵,它將通過(guò)使用表拆分映射到與所有者相同的表。
示例代碼:
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; }
}
八.函數(shù)映射
EF支持映射數(shù)據(jù)庫(kù)中定義的函數(shù),可以在LINQ查詢中使用。
需要在?DbContext?中定義一個(gè)靜態(tài)方法,并且使用?DbFunctionAttribute?特性。
示例代碼:
public class BloggingContext : DbContext
{
? ? [DbFunction]
? ? public static int PostReadCount(int blogId)
? ? {
? ? ? ? throw new Exception();
? ? }
}
這樣的方法是自動(dòng)注冊(cè)。一旦注冊(cè)了方法,您就可以在查詢的任何地方使用它。
?要注意的幾件事:
按照慣例,在生成SQL時(shí),該方法的名稱用作函數(shù)的名稱(在本例中是用戶定義的函數(shù)),但可以在方法注冊(cè)期間重寫(xiě)名稱和schema。
目前只支持標(biāo)量函數(shù)
EF Core遷移將不負(fù)責(zé)創(chuàng)建它,您必須在數(shù)據(jù)庫(kù)中創(chuàng)建映射函數(shù)
九.code first 實(shí)體配置
在EF6可以通過(guò)?EntityTypeConfiguraiton?封裝特定實(shí)體類(lèi)型的配置代碼,在EF Core2.0中,這個(gè)特性回來(lái)了(EF Core 之前的 core版本不支持)。
示例代碼:
class CustomerConfiguration : IEntityTypeConfiguration<Customer>
{
? public void Configure(EntityTypeBuilder<Customer> builder)
? {
? ? ?builder.HasKey(c => c.AlternateKey);
? ? ?builder.Property(c => c.Name).HasMaxLength(200);
? ?}
}
...
// 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;
? ? }
}
本人英語(yǔ)水平有限,如有翻譯不對(duì)的地方,歡迎批評(píng)指正。
原文地址:http://www.cnblogs.com/stulzq/p/7366044.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的Entity Framework Core 2.0 新特性的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: .NET Core 2.0 的dll实时
- 下一篇: Azure与Scott Guthrie: