EF Core 5.0'da hataya neden olan değişiklikler
Aşağıdaki API ve davranış değişiklikleri, EF Core 5.0.0'a güncelleştirilen mevcut uygulamaları bozma potansiyeline sahiptir.
Özet
Orta düzeyde etki eden değişiklikler
EF Core 5.0 .NET Framework'i desteklemiyor
Eski davranış
EF Core 3.1, .NET Framework tarafından desteklenen .NET Standard 2.0'ı hedefler.
Yeni davranış
EF Core 5.0, .NET Framework tarafından desteklenmeyen .NET Standard 2.1'i hedefler. Bu, EF Core 5.0'ın .NET Framework uygulamalarıyla kullanılamayacağı anlamına gelir.
Neden
Bu, tek bir .NET hedef çerçevesiyle birleştirmeyi hedefleyen .NET ekipleri arasında daha geniş bir hareketin bir parçasıdır. Daha fazla bilgi için .NET Standard'ın geleceğine bakın.
Risk Azaltıcı Etkenler
.NET Framework uygulamaları, uzun süreli bir destek (LTS) sürümü olan EF Core 3.1'i kullanmaya devam edebilir. Alternatif olarak, uygulamalar her ikisi de .NET Standard 2.1'i destekleyen .NET Core 3.1 veya .NET 5 kullanacak şekilde güncelleştirilebilir.
IProperty.GetColumnName() artık kullanımdan kaldırıldı
Eski davranış
GetColumnName()
bir özelliğin eşlendiği sütunun adını döndürdü.
Yeni davranış
GetColumnName()
yine de bir özelliğin eşlendiği bir sütunun adını döndürür, ancak EF Core 5 TPT'yi ve bu eşlemelerin aynı özellik için farklı sütun adlarını kullanabileceği bir görünüm veya işlevle eş zamanlı eşlemeyi desteklediğinden bu davranış artık belirsizdir.
Neden
Kullanıcıları daha doğru bir aşırı yüklemeye yönlendirmek için bu yöntemi kullanım dışı olarak işaretledik - GetColumnName(IProperty, StoreObjectIdentifier).
Risk Azaltıcı Etkenler
Varlık türü tek bir tabloyla eşlenmişse ve hiçbir zaman görünümlere, işlevlere veya birden çok tabloya eşlenmemişse, GetColumnBaseName(IReadOnlyProperty) tablo adını almak için EF Core 5.0 ve 6.0'da kullanılabilir. Örnek:
var columnName = property.GetColumnBaseName();
EF Core 7.0'da, bu yeniden basit, tek tablolu eşlemelerde olduğu gibi davranan yeni GetColumnName
ile değiştirilebilir.
Varlık türü görünümlere, işlevlere veya birden çok tabloya eşlenmiş olabilirse, tabloyu, görünümü veya işlevi kimliklendirmek için bir StoreObjectIdentifier alınmalıdır. Bu daha sonra bu depo nesnesinin sütun adını almak için kullanılabilir. Örnek:
var columnName = property.GetColumnName(StoreObjectIdentifier.Table("Users", null)));
Ondalıklar için duyarlık ve ölçek gereklidir
Eski davranış
EF Core normalde nesneler üzerinde SqlParameter duyarlık ve ölçek ayarlamadı. Bu, tam duyarlık ve ölçeğin SQL Server'a gönderildiği ve bu noktada SQL Server'ın veritabanı sütununun duyarlığı ve ölçeğine göre yuvarlanacağı anlamına gelir.
Yeni davranış
EF Core artık EF Core modelindeki özellikler için yapılandırılan değerleri kullanarak parametrelerin duyarlığı ve ölçeğini ayarlar. Bu, yuvarlamanın artık SqlClient'da gerçekleştiği anlamına gelir. Sonuç olarak, yapılandırılan duyarlık ve ölçek veritabanı duyarlığı ve ölçeğiyle eşleşmiyorsa, görülen yuvarlama değişebilir.
Neden
Always Encrypted dahil olmak üzere daha yeni SQL Server özellikleri, parametre modellerinin tam olarak belirtilmiş olmasını gerektirir. Buna ek olarak, SqlClient ondalık değerleri keserek SQL Server davranışıyla eşleştirmek yerine yuvarlamada bir değişiklik yaptı. Bu, EF Core'un doğru yapılandırılmış ondalık değerlerin davranışını değiştirmeden bu modelleri ayarlamasını mümkün hale getirdi.
Risk Azaltıcı Etkenler
Duyarlık ve ölçek içeren bir tür adı kullanarak ondalık özelliklerinizi eşleyin. Örnek:
public class Blog
{
public int Id { get; set; }
[Column(TypeName = "decimal(16, 5)")]
public decimal Score { get; set; }
}
Veya model oluşturma API'lerinde kullanın HasPrecision
. Örnek:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().Property(e => e.Score).HasPrecision(16, 5);
}
Sorumludan bağımlıya gerekli veya boş değer atanamayan gezinti farklı semantiklere sahip
Eski davranış
Yalnızca sorumluya yönelik gezintiler gerektiği gibi yapılandırılabilir. Bu nedenle, bağımlı (yabancı anahtarı içeren varlık) gezintisinde kullanmak RequiredAttribute
veya bunu null atanamaz olarak işaretlemek bunun yerine tanımlama varlık türünde yabancı anahtarı oluşturur.
Yeni davranış
Gerekli bağımlılar için eklenen destekle, artık herhangi bir başvuru gezintisini gerektiği gibi işaretlemek mümkündür, yani yukarıda gösterilen örnekte yabancı anahtar ilişkinin diğer tarafında tanımlanır ve özellikler gerekli olarak işaretlenmez.
Bağımlı uç belirtilmeden önce çağrılması IsRequired
artık belirsiz:
modelBuilder.Entity<Blog>()
.HasOne(b => b.BlogImage)
.WithOne(i => i.Blog)
.IsRequired()
.HasForeignKey<BlogImage>(b => b.BlogForeignKey);
Neden
Yeni davranış, gerekli bağımlılar için desteği etkinleştirmek için gereklidir (bkz. #12100).
Risk Azaltıcı Etkenler
gezintiden bağımlıya öğesini kaldırın RequiredAttribute
ve bunun yerine sorumlusuna gezintiye yerleştirin veya içindeki ilişkiyi OnModelCreating
yapılandırın:
modelBuilder.Entity<Blog>()
.HasOne(b => b.BlogImage)
.WithOne(i => i.Blog)
.HasForeignKey<BlogImage>(b => b.BlogForeignKey)
.IsRequired();
Sorgu tanımlama, sağlayıcıya özgü yöntemlerle değiştirilir
Eski davranış
Varlık türleri, Çekirdek düzeyinde sorgu tanımlamak için eşlendi. Varlık türünün sorgu kökünde varlık türü her kullanıldığında, herhangi bir sağlayıcı için tanımlama sorgusuyla değiştirildi.
Yeni davranış
Sorgu tanımlama API'leri kullanım dışıdır. Sağlayıcıya özgü yeni API'ler kullanıma sunulmuştur.
Neden
Sorgunun içinde her sorgu kökü kullanıldığında sorguların tanımlanması değiştirme sorgusu olarak uygulanırken birkaç sorunu vardı:
- Sorgu tanımlama yöntemi kullanarak
new { ... }
Select
varlık türünü yansıtıyorsa, bunu bir varlık olarak tanımlamak için ek çalışma gerekir ve EF Core'un sorgudaki nominal türleri nasıl değerlendirdiğiyle tutarsız hale getirebilirsiniz. - İlişkisel sağlayıcıların
FromSql
HALA LINQ ifade formunda SQL dizesini geçirmek için gereklidir.
Başlangıçta tanımlama sorguları, anahtarsız varlıklar için Bellek İçi sağlayıcıyla kullanılacak istemci tarafı görünümleri olarak tanıtıldı (ilişkisel veritabanlarındaki veritabanı görünümlerine benzer). Bu tür bir tanım, uygulamanın bellek içi veritabanında test edilmesine olanak sağlar. Daha sonra, yararlı olan ancak tutarsız ve anlaşılması zor davranışlar getiren geniş kapsamlı bir şekilde uygulanabilir hale geldi. Biz de kavramı basitleştirmeye karar verdik. LinQ tabanlı tanımlama sorgusunu bellek içi sağlayıcıya özel hale getirdik ve bunları farklı şekilde ele aldık. Daha fazla bilgi için bu soruna bakın.
Risk Azaltıcı Etkenler
İlişkisel sağlayıcılar için içinde yöntemini OnModelCreating
kullanın ToSqlQuery
ve varlık türü için kullanılacak bir SQL dizesi geçirin.
Bellek İçi sağlayıcısı için içindeki yöntemini OnModelCreating
kullanın ToInMemoryQuery
ve varlık türü için kullanılacak linq sorgusunu geçirin.
Null olmayan başvuru gezintilerinin üzerine sorgular yazılmaz
Eski davranış
EF Core 3.1'de, null olmayan değerlere hevesle başlatılan başvuru gezintileri bazen anahtar değerlerinin eşleşip eşleşmediğine bakılmaksızın veritabanındaki varlık örnekleri tarafından üzerine yazılabilir. Ancak, diğer durumlarda EF Core 3.1 tam tersini yapar ve var olan null olmayan değeri bırakır.
Yeni davranış
EF Core 5.0'dan başlayarak, null olmayan başvuru gezintileri hiçbir zaman sorgudan döndürülen örnekler tarafından üzerine yazılmaz.
Boş bir koleksiyona yönelik bir koleksiyon gezintisinin hevesle başlatılmasının hala desteklendiğini unutmayın.
Neden
Bir başvuru gezinti özelliğinin "boş" varlık örneğine başlatılması belirsiz bir duruma neden olur. Örnek:
public class Blog
{
public int Id { get; set; }
public Author Author { get; set; ) = new Author();
}
Normalde Bloglar ve Yazarlar için bir sorgu önce örnekler oluşturur Blog
ve ardından veritabanından döndürülen verilere göre uygun Author
örnekleri ayarlar. Ancak, bu durumda her Blog.Author
özellik zaten boş Author
bir olarak başlatılır. EF Core'un bu örneğin "boş" olduğunu bilmesinin hiçbir yolu yoktur. Bu nedenle bu örneğin üzerine yazmak, geçerli Author
bir öğesini sessizce atabilir. Bu nedenle, EF Core 5.0 artık tutarlı bir şekilde zaten başlatılmış bir gezintinin üzerine yazmıyor.
Bu yeni davranış çoğu durumda EF6'nın davranışıyla da uyumlu olsa da, araştırma sırasında EF6'da bazı tutarsızlık durumları da bulduk.
Risk Azaltıcı Etkenler
Bu kesmeyle karşılaşılırsa, düzeltme başvuru gezinti özelliklerini hevesle başlatmayı durdurmaktır.
ToView() geçişler tarafından farklı şekilde ele alınır
Eski davranış
Çağrı ToView(string)
, geçişlerin varlık türünü bir görünümle eşlemeye ek olarak yoksaymalarına neden oldu.
Yeni davranış
Şimdi ToView(string)
varlık türünü bir görünüme eşlemeye ek olarak tabloyla eşlenmemiş olarak işaretler. Bu, EF Core 5'e yükselttikten sonra ilk geçişin, bu varlık türü için varsayılan tabloyu artık yoksayılmadığından bırakmayı denemesine neden olur.
Neden
EF Core artık bir varlık türünün aynı anda hem tabloya hem de görünüme eşlenmesine izin verir, bu nedenle ToView
artık geçişler tarafından yoksayılması gerektiğini gösteren geçerli bir gösterge değildir.
Risk Azaltıcı Etkenler
Eşlenen tabloyu geçişlerin dışında olarak işaretlemek için aşağıdaki kodu kullanın:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().ToTable("UserView", t => t.ExcludeFromMigrations());
}
ToTable(null), varlık türünü tabloyla eşlenmemiş olarak işaretler
Eski davranış
ToTable(null)
tablo adını varsayılana sıfırlar.
Yeni davranış
ToTable(null)
şimdi varlık türünü herhangi bir tabloyla eşlenmemiş olarak işaretler.
Neden
EF Core artık bir varlık türünün aynı anda hem tabloya hem de görünüme eşlenmesine izin verir, bu nedenle ToTable(null)
herhangi bir tabloyla eşlenmediğini belirtmek için kullanılır.
Risk Azaltıcı Etkenler
Tablo adı bir görünüme veya DbFunction'a eşlenmemişse varsayılan olarak sıfırlamak için aşağıdaki kodu kullanın:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().Metadata.RemoveAnnotation(RelationalAnnotationNames.TableName);
}
Düşük etkili değişiklikler
SQLite NTS uzantısından HasGeometricDimension yöntemi kaldırıldı
Eski davranış
HasGeometricDimension, geometri sütunlarında ek boyutları (Z ve M) etkinleştirmek için kullanıldı. Ancak, yalnızca veritabanı oluşturmayı etkilemiştir. Ek boyutlara sahip değerleri sorgulamak için belirtilmesi gereksizdi. Ayrıca, ek boyutlarla değer eklerken veya güncelleştirirken de düzgün çalışmadı (bkz. #14257).
Yeni davranış
Geometri değerlerinin ek boyutlar (Z ve M) ile eklenmesini ve güncelleştirilmesini etkinleştirmek için, boyutun sütun türü adının bir parçası olarak belirtilmesi gerekir. Bu API, SpatiaLite'in AddGeometryColumn işlevinin temel davranışıyla daha yakından eşleşir.
Neden
Sütun türündeki boyutu belirttikten sonra HasGeometricDimension kullanmak gereksiz ve gereksiz olduğundan HasGeometricDimension'ı tamamen kaldırdık.
Risk Azaltıcı Etkenler
Boyutu belirtmek için kullanın HasColumnType
:
modelBuilder.Entity<GeoEntity>(
x =>
{
// Allow any GEOMETRY value with optional Z and M values
x.Property(e => e.Geometry).HasColumnType("GEOMETRYZM");
// Allow only POINT values with an optional Z value
x.Property(e => e.Point).HasColumnType("POINTZ");
});
Azure Cosmos DB: Bölüm anahtarı artık birincil anahtara eklendi
Eski davranış
Bölüm anahtarı özelliği yalnızca öğesini içeren id
alternatif anahtara eklendi.
Yeni davranış
Bölüm anahtarı özelliği artık kurala göre birincil anahtara da eklenir.
Neden
Bu değişiklik, modelin Azure Cosmos DB semantiğiyle daha uyumlu olmasını sağlar ve ve bazı sorguların Find
performansını artırır.
Risk Azaltıcı Etkenler
Bölüm anahtarı özelliğinin birincil anahtara eklenmesini önlemek için içinde yapılandırın OnModelCreating
.
modelBuilder.Entity<Blog>()
.HasKey(b => b.Id);
Azure Cosmos DB: id
özelliği olarak yeniden adlandırıldı __id
Eski davranış
JSON özelliğine id
eşlenen gölge özelliği de olarak adlandırılmıştır id
.
Yeni davranış
Kural tarafından oluşturulan gölge özelliği artık olarak adlandırılır __id
.
Neden
Bu değişiklik özelliğin varlık türündeki id
mevcut bir özellik ile çakışma olasılığını düşürür.
Risk Azaltıcı Etkenler
3.x davranışına geri dönmek için içindeki özelliğini OnModelCreating
yapılandırınid
.
modelBuilder.Entity<Blog>()
.Property<string>("id")
.ToJsonProperty("id");
Azure Cosmos DB: bayt[] artık sayı dizisi yerine base64 dizesi olarak depolanıyor
Eski davranış
Bayt[] türündeki özellikler bir sayı dizisi olarak depolandı.
Yeni davranış
Bayt[] türündeki özellikler artık base64 dizesi olarak depolanır.
Neden
Bayt[] öğesinin bu gösterimi, beklentilerle daha iyi uyumludur ve ana JSON serileştirme kitaplıklarının varsayılan davranışıdır.
Risk Azaltıcı Etkenler
Sayı dizileri olarak depolanan mevcut veriler yine de doğru sorgulanır, ancak şu anda ekleme davranışını değiştirmenin desteklenen bir yolu yoktur. Bu sınırlama senaryonuzu engelliyorsa bu sorunla ilgili yorumda bulunabilirsiniz
Azure Cosmos DB: GetPropertyName ve SetPropertyName yeniden adlandırıldı
Eski davranış
Daha önce uzantı yöntemleri ve olarak adlandırılıyordu GetPropertyName
SetPropertyName
Yeni davranış
Eski API kaldırıldı ve yeni yöntemler eklendi: GetJsonPropertyName
, SetJsonPropertyName
Neden
Bu değişiklik, bu yöntemlerin neleri yapılandırıyor olduğuyla ilgili belirsizliği ortadan kaldırır.
Risk Azaltıcı Etkenler
Yeni API'yi kullanın.
Varlık durumu Ayrılmamış, Güncelleştirilmiş veya Silinmiş olarak değiştirildiğinde değer oluşturucuları çağrılır
Eski davranış
Değer oluşturucuları yalnızca varlık durumu Eklendi olarak değiştirildiğinde çağrılır.
Yeni davranış
Varlık durumu Ayrılmamış, Güncelleştirildi veya Silindi olarak değiştirildiğinde ve özellik varsayılan değerleri içerdiğinde artık değer oluşturucuları çağrılır.
Neden
Bu değişiklik, veri deposunda kalıcı olmayan ve değerlerinin her zaman istemcide oluşturulmasını sağlayan özelliklerle ilgili deneyimi geliştirmek için gerekliydi.
Risk Azaltıcı Etkenler
Değer oluşturucunun çağrılmasını önlemek için, durum değiştirilmeden önce özelliğine varsayılan olmayan bir değer atayın.
IMigrationsModelDiffer artık IRelationalModel kullanıyor
Eski davranış
IMigrationsModelDiffer
API kullanılarak IModel
tanımlanmıştır.
Yeni davranış
IMigrationsModelDiffer
API artık kullanıyor IRelationalModel
. Ancak model anlık görüntüsü hala yalnızca IModel
bu kod uygulamanın bir parçası olduğu için içerir ve Entity Framework daha büyük bir hataya neden olan değişiklik yapmadan bunu değiştiremez.
Neden
IRelationalModel
veritabanı şemasının yeni eklenen bir gösterimidir. Farkları bulmak için bunu kullanmak daha hızlı ve daha doğru olur.
Risk Azaltıcı Etkenler
modeli ile modeli snapshot
context
ile karşılaştırmak için aşağıdaki kodu kullanın:
var dependencies = context.GetService<ProviderConventionSetBuilderDependencies>();
var relationalDependencies = context.GetService<RelationalConventionSetBuilderDependencies>();
var typeMappingConvention = new TypeMappingConvention(dependencies);
typeMappingConvention.ProcessModelFinalizing(((IConventionModel)modelSnapshot.Model).Builder, null);
var relationalModelConvention = new RelationalModelConvention(dependencies, relationalDependencies);
var sourceModel = relationalModelConvention.ProcessModelFinalized(snapshot.Model);
var modelDiffer = context.GetService<IMigrationsModelDiffer>();
var hasDifferences = modelDiffer.HasDifferences(
((IMutableModel)sourceModel).FinalizeModel().GetRelationalModel(),
context.Model.GetRelationalModel());
Bu deneyimi 6.0'da geliştirmeyi planlıyoruz (bkz. #22031)
Ayırıcılar salt okunur
Eski davranış
Çağırmadan önce ayrımcı değeri değiştirmek mümkündü SaveChanges
Yeni davranış
Yukarıdaki durumda bir özel durum oluşturulur.
Neden
EF, hala izlenirken varlık türünün değişmesini beklemez, bu nedenle ayırıcı değerin değiştirilmesi bağlamı tutarsız bir durumda bırakır ve bu da beklenmeyen davranışa neden olabilir.
Risk Azaltıcı Etkenler
Ayrıştırıcı değerinin değiştirilmesi gerekiyorsa ve bağlam çağrıldıktan SaveChanges
hemen sonra atılacaksa, ayrıştırıcı değiştirilebilir hale getirilebilir:
modelBuilder.Entity<BaseEntity>()
.Property<string>("Discriminator")
.Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Save);
Sağlayıcıya özgü EF. InMemory sağlayıcısı için işlev yöntemleri oluşturma
Eski davranış
Sağlayıcıya özgü EF. İşlev yöntemleri, inMemory sağlayıcısında yürütülmelerine izin veren istemci yürütme için uygulama içeriyordu. Örneğin, EF.Functions.DateDiffDay
InMemory sağlayıcısı üzerinde çalışan Sql Server'a özgü bir yöntemdir.
Yeni davranış
Sağlayıcıya özgü yöntemler, istemci tarafında değerlendirilmelerini engellemek için yöntem gövdesinde bir özel durum oluşturacak şekilde güncelleştirildi.
Neden
Sağlayıcıya özgü yöntemler bir veritabanı işleviyle eşler. Eşlenen veritabanı işlevi tarafından gerçekleştirilir hesaplama linq istemci tarafında her zaman çoğaltılamaz. İstemcide aynı yöntemi yürütürken sunucudan elde edilen sonucun farklı olması neden olabilir. Bu yöntemler LINQ'te belirli veritabanı işlevlerine çevirmek için kullanıldığından, istemci tarafında değerlendirilmeleri gerekmez. InMemory sağlayıcısı farklı bir veritabanı olduğundan, bu yöntemler bu sağlayıcı için kullanılamaz. Bunları InMemory sağlayıcısı veya bu yöntemleri çevirmeyen başka bir sağlayıcı için yürütmeye çalışmak bir özel durum oluşturur.
Risk Azaltıcı Etkenler
Veritabanı işlevlerinin davranışını doğru bir şekilde taklit etmenin bir yolu olmadığından, bunları içeren sorguları üretimdekiyle aynı türde bir veritabanında test etmelisiniz.
IndexBuilder.HasName artık kullanımdan kaldırıldı
Eski davranış
Daha önce, belirli bir özellik kümesi üzerinde yalnızca bir dizin tanımlanabilirdi. Dizinin veritabanı adı IndexBuilder.HasName kullanılarak yapılandırıldı.
Yeni davranış
Artık aynı kümede veya özelliklerde birden çok dizine izin verilir. Bu dizinler artık modeldeki bir adla ayırt edilir. Kural gereği, model adı veritabanı adı olarak kullanılır; ancak HasDatabaseName kullanılarak bağımsız olarak da yapılandırılabilir.
Neden
Gelecekte, aynı özellik kümesinde farklı harmanlamalara sahip hem artan hem de azalan dizinleri veya dizinleri etkinleştirmek istiyoruz. Bu değişiklik bizi bu yönde başka bir adıma taşır.
Risk Azaltıcı Etkenler
Daha önce IndexBuilder.HasName'i çağıran tüm kodlar bunun yerine HasDatabaseName'i çağıracak şekilde güncelleştirilmelidir.
Projeniz EF Core 2.0.0 sürümünden önce oluşturulan geçişleri içeriyorsa, bu dosyalardaki uyarıyı güvenle yoksayabilir ve ekleyerek #pragma warning disable 612, 618
bunu gizleyebilirsiniz.
Ters mühendislik uygulanmış modellerin iskelesini oluşturmak için bir çoğullaştırıcı eklenmiştir
Eski davranış
Daha önce veritabanı şemasının tersine mühendislik işlemi yaparak DbContext ve varlık türlerinin iskelesini oluştururken DbSet ve koleksiyon gezinti adlarını çoğullaştırmak ve tablo adlarını tekilleştirmek için ayrı bir çoğullaştırıcı paketi yüklemeniz gerekiyordu.
Yeni davranış
EF Core artık Humanizer kitaplığını kullanan bir çoğullaştırıcı içerir. Bu, Visual Studio'da değişken adları önermek için kullanılan kitaplıktır.
Neden
Koleksiyon özellikleri için çoğul sözcük biçimleri, türler ve başvuru özellikleri için tekil formlar kullanmak .NET'te idiomatic'tir.
Risk Azaltıcı Etkenler
Çoğullaştırıcıyı devre dışı bırakmak için açık dotnet ef dbcontext scaffold
seçeneğini veya -NoPluralize
üzerindeki Scaffold-DbContext
anahtarını kullanın--no-pluralize
.
INavigationBase, atlama gezintilerini desteklemek için bazı API'lerdeki INavigation'ın yerini alır
Eski davranış
5.0 öncesi EF Core, arabirim tarafından INavigation
temsil edilen yalnızca bir gezinti özelliği biçimini destekliyordu.
Yeni davranış
EF Core 5.0, "gezintileri atla" kullanan çoka çok ilişkiler sunar. Bunlar arabirimiyle ISkipNavigation
temsil edilir ve işlevlerinin INavigation
çoğu ortak bir temel arabirime gönderilmiştir: INavigationBase
.
Neden
Normal ve atlama gezintileri arasındaki işlevlerin çoğu aynıdır. Ancak, dahil olan FK'ler doğrudan ilişkinin iki ucunda değil, birleştirme varlığında olduğundan, atlama gezintilerinin yabancı tuşlarla normal gezintilerden farklı bir ilişkisi vardır.
Risk Azaltıcı Etkenler
Çoğu durumda uygulamalar başka bir değişiklik olmadan yeni temel arabirimi kullanmaya geçebilir. Ancak, gezintinin yabancı anahtar özelliklerine erişmek için kullanıldığı durumlarda, uygulama kodu yalnızca normal gezintilerle kısıtlanmalı veya hem normal hem de atlama gezintileri için uygun olanı yapacak şekilde güncelleştirilmelidir.
Ayrıca kullanan Distinct
veya GroupBy
artık desteklenmeyen bağıntılı koleksiyona sahip bazı sorgular
Eski davranış
Daha önce, bağıntılı koleksiyonlar içeren sorgular ve yürütmesine izin vermemizi sağlayan Distinct
bazı sorgular tarafından takip GroupBy
edilir.
GroupBy örneği:
context.Parents
.Select(p => p.Children
.GroupBy(c => c.School)
.Select(g => g.Key))
Distinct
örnek - özellikle Distinct
iç koleksiyon projeksiyonunun birincil anahtarı içermediği sorgular:
context.Parents
.Select(p => p.Children
.Select(c => c.School)
.Distinct())
İç koleksiyonda yinelenen öğeler varsa bu sorgular yanlış sonuçlar döndürebilir, ancak iç koleksiyondaki tüm öğeler benzersizse doğru şekilde çalışır.
Yeni davranış
Bu sorgular artık desteklenmiyor. Sonuçları doğru şekilde oluşturmak için yeterli bilgiye sahip olmadığımızı belirten özel durum oluştu.
Neden
Bağıntılı koleksiyon senaryolarında, koleksiyon varlıklarını doğru üst öğeye atamak için varlığın birincil anahtarını bilmemiz gerekir. İç koleksiyon veya Distinct
kullanmadığındaGroupBy
, eksik birincil anahtar projeksiyona eklenebilir. Ancak ve Distinct
durumunda GroupBy
veya işleminin sonucunu GroupBy
Distinct
değiştireceğinden yapılamıyor.
Risk Azaltıcı Etkenler
İç koleksiyonda veya Distinct
işlemlerinde kullanılmaması GroupBy
için sorguyu yeniden yazın ve bunun yerine istemcide bu işlemleri gerçekleştirin.
context.Parents
.Select(p => p.Children.Select(c => c.School))
.ToList()
.Select(x => x.GroupBy(c => c).Select(g => g.Key))
context.Parents
.Select(p => p.Children.Select(c => c.School))
.ToList()
.Select(x => x.Distinct())
Projeksiyonda Sorgulanabilir tür koleksiyonunun kullanılması desteklenmez
Eski davranış
Daha önce, bazı durumlarda projeksiyonun içinde sorgulanabilir bir türün koleksiyonunu kullanmak mümkündü, örneğin bir List<T>
oluşturucunun bağımsız değişkeni olarak:
context.Blogs
.Select(b => new List<Post>(context.Posts.Where(p => p.BlogId == b.Id)))
Yeni davranış
Bu sorgular artık desteklenmiyor. Sorgulanabilir türünde bir nesne oluşturamadığımızı belirten ve bunun nasıl düzeltilebileceğini öneren özel durum oluşturulur.
Neden
Sorgulanabilir türünde bir nesneyi oluşturamıyoruz, bu nedenle bunun yerine tür kullanılarak List<T>
otomatik olarak oluşturulurlar. Bu durum genellikle çok net olmayan ve bazı kullanıcılar için şaşırtıcı olabilecek tür uyuşmazlığı nedeniyle bir özel duruma neden olabilir. Deseni tanımaya ve daha anlamlı bir özel durum oluşturma kararı aldık.
Risk Azaltıcı Etkenler
Projeksiyonda Queryable nesnesinden sonra çağrı ekleyin ToList()
:
context.Blogs.Select(b => context.Posts.Where(p => p.BlogId == b.Id).ToList())