EF Core 2.0'daki yeni özellikler
.NET Standard 2.0
EF Core artık .NET Standard 2.0'a yöneliktir. Bu da .NET Core 2.0, .NET Framework 4.6.1 ve .NET Standard 2.0 uygulayan diğer kitaplıklarla çalışa bir hizmettir. Desteklenenler hakkında daha fazla bilgi için bkz. Desteklenen .NET Uygulamaları.
Modelleme
Tablo bölme
Artık iki veya daha fazla varlık türü, birincil anahtar sütunlarının paylaşılacak olduğu ve her satırın iki veya daha fazla varlığa karşılık gelen aynı tabloya eşlenebilirsiniz.
Tanımlama ilişkisini (yabancı anahtar özelliklerinin birincil anahtarı oluşturması gereken) bölmeyi kullanmak için tabloyu paylaşan tüm varlık türleri arasında yapılandırılması gerekir:
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");
Bu özellik hakkında daha fazla bilgi için tablo bölme bölümünü okuyun.
Sahip olunan türler
Sahip olunan varlık türü, aynı .NET türünü başka bir sahip olunan varlık türüyle paylaşabilir, ancak yalnızca .NET türü tarafından tanımlanamayyrı, başka bir varlık türünden bir gezinti olması gerekir. Tanımlayan gezintiyi içeren varlık sahibidir. Sahibi sorgularken sahip olunan türler varsayılan olarak dahil edilir.
Kural gereği, sahip olunan tür için bir gölge birincil anahtar oluşturulur ve tablo bölme kullanılarak sahiple aynı tabloya eşlenmiş olur. Bu, EF6'da karmaşık türlerin kullanımına benzer şekilde sahip olunan türlerin kullanımına olanak sağlar:
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; }
}
Bu özellik hakkında daha fazla bilgi için sahip olunan varlık türleri bölümünü okuyun.
Model düzeyinde sorgu filtreleri
EF Core 2.0, Model düzeyi sorgu filtreleri olarak çağırdiğimiz yeni bir özellik içerir. Bu özellik, LINQ sorgu durumlarının (genellikle LINQ Where sorgu işlecine geçirilen bir boole ifadesi) meta veri modelinde (genellikle OnModelCreating içinde) Varlık Türleri üzerinde tanımlandığına olanak sağlar. Bu tür filtreler, dahil veya doğrudan gezinti özelliği başvurularının kullanımı gibi dolaylı olarak başvurulan Varlık Türleri de dahil olmak üzere bu Varlık Türlerini içeren tüm LINQ sorgularına otomatik olarak uygulanır. Bu özelliğin bazı yaygın uygulamaları:
- Yazılımlı silme - Varlık Türleri bir IsDeleted özelliğini tanımlar.
- Çok kiracılı - Varlık Türü bir TenantId özelliğini tanımlar.
Aşağıda, yukarıda listelenen iki senaryo için özelliği gösteren basit bir örnek velenmiştir:
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);
}
}
Varlık Türü örnekleri için çok katmanlı ve yazılımlı silme uygulayan model düzeyinde bir filtre Post tanımlamış oluruz. Örnek düzeyi özelliğinin DbContext kullanımına dikkat: TenantId . Model düzeyinde filtreler, doğru bağlam örneğinden (sorguyu yürüten bağlam örneği) değeri kullanır.
IgnoreQueryFilters() işleci kullanılarak tek tek LINQ sorguları için filtreler devre dışı bırakılabilir.
Sınırlamalar
- Gezinti başvurularına izin verilmez. Bu özellik geri bildirime göre eklenebilir.
- Filtreler yalnızca bir hiyerarşinin kök Varlık Türü'ne göre tanımlanabilir.
Veritabanı skaler işlev eşlemesi
EF Core 2.0, veritabanı skaler işlevlerinin LINQ sorgularında kullanılamayacak ve veri tabanına çevrilebilir olması için yöntem saplamalarına eşlenen Paul Middleton'dan önemli bir katkı SQL.
Özelliğin nasıl kullanıla sılaya kısa bir açıklaması şu şekildedir:
üzerinde statik bir yöntem DbContext bildirin ve ile bu yönteme not ek açıklamalarını DbFunctionAttribute kullanın:
public class BloggingContext : DbContext
{
[DbFunction]
public static int PostReadCount(int blogId)
{
throw new NotImplementedException();
}
}
Bunun gibi yöntemler otomatik olarak kaydedilir. Kaydedildiktan sonra LINQ sorgusunda yöntemine yapılan çağrılar, aşağıdaki sorgularda yapılan işlev çağrılarına SQL:
var query =
from p in context.Posts
where BloggingContext.PostReadCount(p.Id) > 5
select p;
Dikkat edilecek birkaç şey:
- Kural gereği yöntemin adı, SQL oluşturma sırasında bir işlevin adı (bu durumda kullanıcı tanımlı bir işlev) olarak kullanılır, ancak yöntem kaydı sırasında adı ve şemayı geçersiz kılebilirsiniz.
- Şu anda yalnızca skaler işlevler de desteklemektedir.
- Eşlenen işlevi veritabanında oluşturmanız gerekir. EF Core geçişleri oluşturmakla ilgilenmez.
Önce kod için kendi içinde tür yapılandırması
EF6'da EntityTypeConfiguration'dantüreterek belirli bir varlık türünün ilk kod yapılandırmasını kapsülleyebilirsiniz. 2 EF Core 2.0'da bu düzeni geri getiriyoruz:
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());
Yüksek Performans
DbContext havuzu
ASP.NET Core uygulamasında EF Core kullanmanın temel deseni genellikle bağımlılık ekleme sistemine özel bir DbContext türü kaydetmeyi ve ardından denetleyicilerde oluşturucu parametreleri aracılığıyla bu tür örnekleri elde etmektir. Bu, her istek için yeni bir DbContext örneği oluşturulacak anlamına gelir.
Sürüm 2.0'da yeniden kullanılabilir DbContext örneklerinin havuzunu saydam bir şekilde tanıtan bağımlılık eklemeye özel DbContext türlerini kaydetmek için yeni bir yol tanıtıyoruz. DbContext havuzu kullanmak için, hizmet AddDbContextPool kaydı sırasında AddDbContext yerine kullanın:
services.AddDbContextPool<BloggingContext>(
options => options.UseSqlServer(connectionString));
Bu yöntem kullanılırsa, bir denetleyici tarafından DbContext örneği istenecek zaman önce havuzda kullanılabilir bir örnek olup olamayacaklarını kontrol ederiz. İstek işleme son hale gelir, örnekteki tüm durum sıfırlanır ve örneğin kendisi havuza döndürülür.
Bu, kavramsal olarak bağlantı havuzulamanın ADO.NET sağlayıcılarda çalışmayla benzerdir ve DbContext örneğinin başlatma maliyetinin bir kaçı tasarruf avantajına sahiptir.
Sınırlamalar
Yeni yöntem, DbContext yönteminde yapılacaklar OnConfiguring() hakkında birkaç sınırlama sağlar.
Uyarı
İstekler arasında paylaşılmaması gereken türetilmiş DbContext sınıfınıza kendi durumunuz (örneğin, özel alanlar) sahip olursanız DbContext Havuzunu kullanmaktan kaçının. EF Core, havuza dbContext örneği eklemeden önce yalnızca farkında olduğu durumu sıfırlar.
Açıkça derlenmiş sorgular
Bu, yüksek ölçekli senaryolarda avantajlar sunmak için tasarlanmış ikinci katılım performansı özelliğidir.
El ile veya açıkça derlenmiş sorgu API'leri, önceki EF sürümlerinde ve ayrıca uygulamaların sorguların çevirisini önbelleğe alan ve yalnızca bir kez hesaplanabiliyor ve birçok kez yürütülabiliyor olması için LINQ to SQL'de kullanılabilir.
Genel olarak EF Core sorgu ifadelerinin karma gösterimine göre sorguları otomatik olarak derleye ve önbelleğe alasa da, bu mekanizma karma ve önbellek arama hesaplamasını atlayarak küçük bir performans kazancı elde etmek için kullanılabilir ve uygulamanın bir temsilcinin çağrılması yoluyla zaten derlenmiş bir sorgu kullanmasına olanak sağlar.
// 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);
}
Değişiklik İzleme
Ekleme, yeni ve mevcut varlıkların graflarını izleyebilir
EF Core çeşitli mekanizmalar aracılığıyla anahtar değerlerin otomatik olarak neslini destekler. Bu özellik kullanılırken, anahtar özelliği CLR varsayılanı ise (genellikle sıfır veya null) bir değer oluşturulur. Bu, bir varlık grafı veya 'a geçirilene ve EF Core bir anahtara sahip olan varlıkları olarak işaretlenirken, anahtar kümesine sahip varlıklar olarak DbContext.AttachDbSet.AttachUnchangedAdded işaretlenir. Bu, oluşturulan anahtarları kullanırken karma yeni ve mevcut varlıkların grafı iliştirmenize yardımcı olur. DbContext.Update ve DbSet.Update aynı şekilde çalışır, ancak anahtar kümesine sahip varlıklar yerine olarak ModifiedUnchanged işaretlenir.
Sorgu
Geliştirilmiş LINQ çevirisi
Veritabanında daha fazla mantık değerlendirilerek (bellek içinde değil) ve gereksiz yere veritabanından daha az veri alınarak daha fazla sorguyu başarıyla yürütmeye olanak sağlar.
GroupJoin geliştirmeleri
Bu çalışma, SQL için oluşturulan veri kümelerini iyiler. Grup birleştirmeleri genellikle isteğe bağlı gezinti özellikleri üzerinde alt sorguların sonucu olur.
FromSql ve ExecuteSqlCommand'de dize ilişkilendirme
C# 6, C# ifadelerinin doğrudan dize değişmez değerine katıştırarak çalışma zamanında dizeler derlemenin güzel bir yolunu sağlayan Dize İlişkisi'ne olanak sağlayan bir özelliktir. 2 EF Core 2.0'da ham SQL dizelerini kabul eden iki birincil API'mize i eklenmiş dizeler için özel destek FromSql ekledik: ve ExecuteSqlCommand . Bu yeni destek, C# dize ilişkilendirmenin "güvenli" bir şekilde kullanılmaya olanak sağlar. Başka bir ifadeyle, çalışma zamanında dinamik olarak SQL ekleme hatalarına karşı koruma SQL şekilde.
Örnek aşağıda verilmiştir:
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();
}
Bu örnekte, SQL biçimi dizesinde katıştırılmış iki değişken vardır. EF Core aşağıdaki adımları SQL:
@p0='London' (Size = 4000)
@p1='Sales Representative' (Size = 4000)
SELECT *
FROM ""Customers""
WHERE ""City"" = @p0
AND ""ContactTitle"" = @p1
EF. Functions.Like()
EF'yi ekledik. LinQ sorgularında çağrılmalarını sağlamak EF Core işlevlerine veya işleçlere eşlene yöntemleri tanımlamak için özel işlevler veya sağlayıcılar tarafından kullanılmaktadır. Bu tür bir yöntemin ilk örneği Like() yöntemidir:
var aCustomers =
from c in context.Customers
where EF.Functions.Like(c.Name, "a%")
select c;
Like() işlevi bellek içinde veritabanı üzerinde çalışırken veya istemci tarafında durum değerlendirmesi yapılması gerekirken kullanışlı olan bir bellek içinde uygulamayla birlikte gelir.
Veritabanı yönetimi
DbContext yapı iskelesi için çoğullaştırma kancası
EF Core 2.0, varlık türü adlarını tekilleştirmek ve DbSet adlarını pluralize etmek için kullanılan yeni bir IPluralizer hizmeti sunmaktadır. Varsayılan uygulama bir operasyon değil, bu nedenle insanların kendi çoğullandırıcılarını kolayca bağlaylayabiliyor olduğu bir kancadır.
Bir geliştiricinin kendi çoğullandırıcılarına kanca atarak nasıl bir şey yaptığının nasıl bir şey olduğunu burada ifade etmek gerekir:
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;
}
}
Diğer
SQLite ADO.NET SQLitePCL.raw'a taşıma
Bu, yerel SQLite ikili dosyalarını farklı platformlarda dağıtmak için Microsoft.Data.Sqlite'da bize daha sağlam bir çözüm sağlar.
Model başına yalnızca bir sağlayıcı
Sağlayıcıların modelle etkileşim kurmasını önemli ölçüde artırır ve kuralların, ek açıklamaların ve akıcı API'lerin farklı sağlayıcılarla çalışmasını kolaylaştırır.
EF Core 2.0 artık kullanılan her farklı sağlayıcı için farklı bir IModel derlemeye devam eder. Bu genellikle uygulama için saydamdır. Bu, yaygın ilişkisel meta veri kavramlarına her zaman , vb. yerine bir çağrı yoluyla erişim sağlandı şekilde alt düzey meta veri API'lerinin .SqlServer basitleştirilmesini .Sqlite kolaylaştırdı.
Birleştirilmiş günlük ve tanılama
Günlüğe kaydetme (ILogger'ı temel alan) ve Tanılama (DiagnosticSource'u temel alan) mekanizmalar artık daha fazla kod paylaşır.
ILogger'a gönderilen iletilerin olay kimlikleri 2.0'da değişmiştir. Olay kimlikleri artık kodda benzersiz EF Core olur. Bu iletiler artık MVC gibi tarafından kullanılan yapılandırılmış günlük kaydı için standart deseni de takip eder.
Günlük kullanıcı kategorileri de değişmiştir. Artık DbLoggerCategoryaracılığıyla erişilen iyi bilinen bir kategori kümesi vardır.
DiagnosticSource olayları artık karşılık gelen iletilerle aynı olay kimliği adlarını ILogger kullanır.