İlgili Verileri YüklemeLoading Related Data

Entity Framework Core, ilişkili varlıkları yüklemek için modelinizdeki gezinti özelliklerini kullanmanıza olanak sağlar.Entity Framework Core allows you to use the navigation properties in your model to load related entities. İlgili verileri yüklemek için kullanılan üç ortak O/RM deseni vardır.There are three common O/RM patterns used to load related data.

  • Eager yüklemesi , ilgili verilerin ilk sorgunun parçası olarak veritabanından yüklendiği anlamına gelir.Eager loading means that the related data is loaded from the database as part of the initial query.
  • Açık yükleme , ilgili verilerin daha sonra veritabanından açıkça yüklendiği anlamına gelir.Explicit loading means that the related data is explicitly loaded from the database at a later time.
  • Yavaş yükleme , gezinti özelliğine erişildiğinde ilgili verilerin veritabanından saydam olarak yüklendiği anlamına gelir.Lazy loading means that the related data is transparently loaded from the database when the navigation property is accessed.

İpucu

Bu makalenin örneğini GitHub ' da görebilirsiniz.You can view this article's sample on GitHub.

Ekip yüklemeEager loading

IncludeSorgu sonuçlarına dahil edilecek ilgili verileri belirtmek için yöntemini kullanabilirsiniz.You can use the Include method to specify related data to be included in query results. Aşağıdaki örnekte, sonuçlarda döndürülen blogların Posts özelliği ilgili gönderileriyle doldurulmuş olacaktır.In the following example, the blogs that are returned in the results will have their Posts property populated with the related posts.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .ToList();
}

İpucu

Entity Framework Core, gezinti özelliklerini daha önce bağlam örneğine yüklenmiş diğer varlıklara otomatik olarak düzeltir.Entity Framework Core will automatically fix-up navigation properties to any other entities that were previously loaded into the context instance. Bu nedenle, bir gezinti özelliği için verileri açıkça bulundurmasanız bile, ilgili varlıkların bazıları veya tümü daha önce yüklenmişse Özellik yine de doldurulmuş olabilir.So even if you don't explicitly include the data for a navigation property, the property may still be populated if some or all of the related entities were previously loaded.

Tek bir sorgudaki birden fazla ilişkilerden ilgili verileri dahil edebilirsiniz.You can include related data from multiple relationships in a single query.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .Include(blog => blog.Owner)
        .ToList();
}

Birden çok düzey dahilIncluding multiple levels

Yöntemini kullanarak ilgili verilerin birden fazla düzeyini dahil etmek için ilişkilerde ayrıntıya gidebilirsiniz ThenInclude .You can drill down through relationships to include multiple levels of related data using the ThenInclude method. Aşağıdaki örnek tüm blogları, ilgili yayınlarını ve her gönderiye ait yazarı yükler.The following example loads all blogs, their related posts, and the author of each post.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Author)
        .ToList();
}

ThenIncludeDaha fazla ilgili veri düzeyi dahil devam etmek için birden çok çağrısı zincirleyebilirsiniz.You can chain multiple calls to ThenInclude to continue including further levels of related data.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Author)
                .ThenInclude(author => author.Photo)
        .ToList();
}

Aynı sorguda birden çok düzeyden ve birden çok kökten ilgili verileri dahil etmek için tüm bunları birleştirebilirsiniz.You can combine all of this to include related data from multiple levels and multiple roots in the same query.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Author)
                .ThenInclude(author => author.Photo)
        .Include(blog => blog.Owner)
            .ThenInclude(owner => owner.Photo)
        .ToList();
}

Dahil edilen varlıklardan biri için birden fazla ilgili varlık eklemek isteyebilirsiniz.You may want to include multiple related entities for one of the entities that is being included. Örneğin, sorgulama yaparken, ve ' Blogs Posts nin her ikisini de dahil etmek istersiniz Author Tags Posts .For example, when querying Blogs, you include Posts and then want to include both the Author and Tags of the Posts. Bunu yapmak için, kökden başlayarak her bir içerme yolunu belirtmeniz gerekir.To do this, you need to specify each include path starting at the root. Örneğin Blog -> Posts -> Author ve Blog -> Posts -> Tags.For example, Blog -> Posts -> Author and Blog -> Posts -> Tags. Bu, gereksiz birleşimler alacağınız anlamına gelmez; Çoğu durumda, SQL oluştururken EF birleştirmeleri birleştirecek.This does not mean you will get redundant joins; in most cases, EF will consolidate the joins when generating SQL.

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Author)
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Tags)
        .ToList();
}

Tek ve bölünmüş sorgularSingle and split queries

Not

Bu özellik EF Core 5,0 ' de kullanıma sunulmuştur.This feature is introduced in EF Core 5.0.

İlişkisel veritabanlarında, tüm ilgili varlıklar varsayılan olarak, birleşimlere giriş yoluyla yüklenir:In relational databases, all related entities are by default loaded by introducing JOINs:

SELECT [b].[BlogId], [b].[OwnerId], [b].[Rating], [b].[Url], [p].[PostId], [p].[AuthorId], [p].[BlogId], [p].[Content], [p].[Rating], [p].[Title]
FROM [Blogs] AS [b]
LEFT JOIN [Post] AS [p] ON [b].[BlogId] = [p].[BlogId]
ORDER BY [b].[BlogId], [p].[PostId]

Tipik bir blogda birden çok ilgili gönderi varsa, bu Gönderilerin satırları blogunuzun bilgilerini yine, bu da "Kartezyen açılım" sorununa görünür.If a typical blog has multiple related posts, rows for these posts will duplicate the blog's information, leading to the so-called "cartesian explosion" problem. Birden çok çoktan çoğa ilişki yüklendiği için, çoğaltılan verilerin miktarı büyütülür ve uygulamanızın performansını olumsuz yönde etkileyebilir.As more one-to-many relationships are loaded, the amount of duplicated data may grow and adversely affect the performance of your application.

EF, belirli bir LINQ sorgusunun birden çok SQL sorgusuna bölünmesi gerektiğini belirtmenize olanak tanır.EF allows you to specify that a given LINQ query should be split into multiple SQL queries. Birleşimler yerine, bölünmüş sorguları her bir çoktan çoğa gezinti için ek bir SQL sorgusu gerçekleştirir:Instead of JOINs, split queries perform an additional SQL query for each included one-to-many navigation:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
        .AsSplitQuery()
        .ToList();
}

Bu, aşağıdaki SQL 'i oluşturur:This will produce the following SQL:

SELECT [b].[BlogId], [b].[OwnerId], [b].[Rating], [b].[Url]
FROM [Blogs] AS [b]
ORDER BY [b].[BlogId]

SELECT [p].[PostId], [p].[AuthorId], [p].[BlogId], [p].[Content], [p].[Rating], [p].[Title], [b].[BlogId]
FROM [Blogs] AS [b]
INNER JOIN [Post] AS [p] ON [b].[BlogId] = [p].[BlogId]
ORDER BY [b].[BlogId]

Bu, birleşimlerle ve Kartezyen patlaması ile ilişkili performans sorunlarını önleyip, bazı dezavantajları da vardır:While this avoids the performance issues associated with JOINs and cartesian explosion, it also has some drawbacks:

  • Veritabanlarının çoğu tek sorgu için veri tutarlılığını garanti ederken, birden çok sorgu için böyle bir garanti yoktur.While most databases guarantee data consistency for single queries, no such guarantees exist for multiple queries. Diğer bir deyişle, sorgular yürütüldüğü için veritabanı eşzamanlı olarak güncelleştirilirse, sonuçta elde edilen veriler tutarlı olmayabilir.This means that if the database is being updated concurrently as your queries are being executed, resulting data may not be consistent. Bu, sorguları bir seri hale getirilebilir veya anlık görüntü işleminde sarmalayarak, bu, kendi performans sorunları oluştursa da azaltılabilir.This may be mitigated by wrapping the queries in a serializable or snapshot transaction, although this may create performance issues of its own. Daha fazla ayrıntı için veritabanınızın belgelerine başvurun.Consult your database's documentation for more details.
  • Her sorgu şu anda veritabanınıza ek bir ağ gidiş dönüşü anlamına gelir; Bu durum, özellikle de veritabanı gecikmesi yüksek (örneğin, bulut Hizmetleri) olan performansı düşürebilir.Each query currently implies an additional network roundtrip to your database; this can degrade performance, especially where latency to the database is high (e.g. cloud services). EF Core sorguları tek bir gidiş dönüş halinde toplu hale getirerek bu gelecekte iyileştirilmesine sahip olur.EF Core will improve this in the future by batching the queries into a single roundtrip.
  • Bazı veritabanları aynı anda birden çok sorgunun sonuçlarını (MARS, SQLite ile SQL Server) kullanılmasına izin verirken, çoğu belirli bir noktada yalnızca tek bir sorgunun etkin olmasını sağlar.While some databases allow consuming the results of multiple queries at the same time (SQL Server with MARS, Sqlite), most allow only a single query to be active at any given point. Bu, önceki sorguların tüm sonuçlarının daha sonraki sorguları yürütmeden önce uygulamanızın belleğinde ara belleğe alınmasının gerektiği anlamına gelir ve bellek gereksinimlerinizi potansiyel olarak önemli bir şekilde artırır.This means that all results from earlier queries must be buffered in your application's memory before executing later queries, increasing your memory requirements in a potentially significant way.

Ne yazık ki, tüm senaryolara uyan ilgili varlıkların yüklenmesi için bir strateji yoktur.Unfortunately, there isn't one strategy for loading related entities that fits all scenarios. Tek ve bölünmüş sorguların olumlu ve olumsuz yönlerini dikkatle değerlendirin ve gereksinimlerinize uygun olanı seçin.Carefully consider the advantages and disadvantages of single and split queries, and select the one that fits your needs.

Not

Bire bir ilgili varlıklar her zaman birleşimler aracılığıyla yüklenir, çünkü bunun performans etkisi yoktur.One-to-one related entities are always loaded via JOINs, as this has no performance impact.

Şu anda, SQL Server sorgu bölme kullanımı MultipleActiveResultSets=true bağlantı dizeniz için ayarları gerektirir.At the moment, use of query splitting on SQL Server requires settings MultipleActiveResultSets=true in your connection string. Bu gereksinim, gelecekteki bir önizlemede kaldırılacak.This requirement will be removed in a future preview.

EF Core 5,0 ' nin gelecekteki önizlemeleri, bağlam için varsayılan olarak sorgu bölme belirtilmesine izin verir.Future previews of EF Core 5.0 will allow specifying query splitting as the default for your context.

Filtrelenen eklemeFiltered include

Not

Bu özellik EF Core 5,0 ' de kullanıma sunulmuştur.This feature is introduced in EF Core 5.0.

İlgili verileri yüklemeye dahil etme işlemini uygularken, sonuçları filtrelemeye ve sıralamaya izin veren dahil edilen koleksiyon gezintisinde bazı sıralanabilir işlemleri uygulayabilirsiniz.When applying Include to load related data, you can apply certain enumerable operations on the included collection navigation, which allows for filtering and sorting of the results.

Desteklenen işlemler şunlardır: Where , OrderBy , OrderByDescending , ThenBy , ThenByDescending , Skip , ve Take .Supported operations are: Where, OrderBy, OrderByDescending, ThenBy, ThenByDescending, Skip, and Take.

Bu tür işlemler, aşağıdaki örnekte gösterildiği gibi Include yöntemine geçirilen lambda içindeki koleksiyon gezintisinde uygulanmalıdır:Such operations should be applied on the collection navigation in the lambda passed to the Include method, as shown in example below:

using (var context = new BloggingContext())
{
    var filteredBlogs = context.Blogs
        .Include(blog => blog.Posts
            .Where(post => post.BlogId == 1)
            .OrderByDescending(post => post.Title)
            .Take(5))
        .ToList();
}

Dahil edilen her gezinme yalnızca bir tane benzersiz filtre işlemleri kümesine izin verir.Each included navigation allows only one unique set of filter operations. Belirli bir koleksiyon gezintisi için birden çok Içerme işlemi uygulandığı durumlarda ( blog.Posts Aşağıdaki örneklerde), filtre işlemleri yalnızca bunlardan birinde belirtilebilir:In cases where multiple Include operations are applied for a given collection navigation (blog.Posts in the examples below), filter operations can only be specified on one of them:

using (var context = new BloggingContext())
{
    var filteredBlogs = context.Blogs
        .Include(blog => blog.Posts.Where(post => post.BlogId == 1))
            .ThenInclude(post => post.Author)
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Tags.OrderBy(postTag => postTag.TagId).Skip(3))
        .ToList();
}

Alternatif olarak, birden çok kez bulunan her gezinti için aynı işlemler uygulanabilir:Alternatively, identical operations can be applied for each navigation that is included multiple times:

using (var context = new BloggingContext())
{
    var filteredBlogs = context.Blogs
        .Include(blog => blog.Posts.Where(post => post.BlogId == 1))
            .ThenInclude(post => post.Author)
        .Include(blog => blog.Posts.Where(post => post.BlogId == 1))
            .ThenInclude(post => post.Tags.OrderBy(postTag => postTag.TagId).Skip(3))
        .ToList();
}

Dikkat

Sorgu izleme durumunda, filtre ekleme sonuçları, Gezinti düzeltmesinedeniyle beklenmeyen bir durum olabilir.In case of tracking queries, results of Filtered Include may be unexpected due to navigation fixup. Daha önce ve değişiklik Izleyicide saklanan tüm ilgili varlıklar, filtrenin gereksinimlerini karşılamadığında bile filtrelenmiş ekleme sorgusunun sonuçlarında mevcut olacaktır.All relevant entities that have been querried for previously and have been stored in the Change Tracker will be present in the results of Filtered Include query, even if they don't meet the requirements of the filter. NoTrackingBu durumlara filtre ekleme sırasında sorguları kullanmayı veya DbContext 'i yeniden oluşturmayı düşünün.Consider using NoTracking queries or re-create the DbContext when using Filtered Include in those situations.

Örnek:Example:

var orders = context.Orders.Where(o => o.Id > 1000).ToList();

// customer entities will have references to all orders where Id > 1000, rathat than > 5000
var filtered = context.Customers.Include(c => c.Orders.Where(o => o.Id > 5000)).ToList();

Türetilmiş türlere dahil etInclude on derived types

Yalnızca ve kullanarak türetilmiş bir tür üzerinde tanımlanan gezintilerden ilgili verileri dahil edebilirsiniz Include ThenInclude .You can include related data from navigations defined only on a derived type using Include and ThenInclude.

Aşağıdaki model veriliyor:Given the following model:

public class SchoolContext : DbContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<School> Schools { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<School>().HasMany(s => s.Students).WithOne(s => s.School);
    }
}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Student : Person
{
    public School School { get; set; }
}

public class School
{
    public int Id { get; set; }
    public string Name { get; set; }

    public List<Student> Students { get; set; }
}

SchoolÖğrenciler olan tüm kişilerin gezinmesinin içerikleri, çeşitli desenler kullanılarak oluşturulabilir:Contents of School navigation of all People who are Students can be eagerly loaded using a number of patterns:

  • cast kullanmausing cast

    context.People.Include(person => ((Student)person).School).ToList()
    
  • Using as işleciusing as operator

    context.People.Include(person => (person as Student).School).ToList()
    
  • Includetürü parametre alan aşırı yüklemesini kullanmastringusing overload of Include that takes parameter of type string

    context.People.Include("School").ToList()
    

Açık yüklemeExplicit loading

API aracılığıyla bir gezinti özelliğini açıkça yükleyebilirsiniz DbContext.Entry(...) .You can explicitly load a navigation property via the DbContext.Entry(...) API.

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Single(b => b.BlogId == 1);

    context.Entry(blog)
        .Collection(b => b.Posts)
        .Load();

    context.Entry(blog)
        .Reference(b => b.Owner)
        .Load();
}

Ayrıca, ilişkili varlıkları döndüren ayrı bir sorgu yürüterek bir gezinti özelliğini açıkça yükleyebilirsiniz.You can also explicitly load a navigation property by executing a separate query that returns the related entities. Değişiklik izleme etkinse, bir varlık yüklenirken EF Core, önceden yüklenmiş olan varlıkların gezinti özelliklerini otomatik olarak ayarlar ve bu, önceden yüklenmiş varlıkların gezinti özelliklerini, yeni yüklenen varlığa başvuracak şekilde ayarlar.If change tracking is enabled, then when loading an entity, EF Core will automatically set the navigation properties of the newly-loaded entitiy to refer to any entities already loaded, and set the navigation properties of the already-loaded entities to refer to the newly-loaded entity.

Ayrıca, bir gezinti özelliğinin içeriğini temsil eden bir LINQ sorgusu da edinebilirsiniz.You can also get a LINQ query that represents the contents of a navigation property.

Bu, ilgili varlıklar üzerinde bir toplama işlecini belleğe yüklemeden çalıştırmak gibi işlemleri yapmanızı sağlar.This allows you to do things such as running an aggregate operator over the related entities without loading them into memory.

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Single(b => b.BlogId == 1);

    var postCount = context.Entry(blog)
        .Collection(b => b.Posts)
        .Query()
        .Count();
}

Ayrıca, hangi ilgili varlıkların belleğe yükleneceğini de filtreleyebilirsiniz.You can also filter which related entities are loaded into memory.

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Single(b => b.BlogId == 1);

    var goodPosts = context.Entry(blog)
        .Collection(b => b.Posts)
        .Query()
        .Where(p => p.Rating > 3)
        .ToList();
}

Geç yüklemeLazy loading

Geç yüklemeyi kullanmanın en basit yolu, Microsoft. EntityFrameworkCore. proxy paketini yüklemek ve ' a çağrı yaparak bunu yapmanızı sağlar UseLazyLoadingProxies .The simplest way to use lazy-loading is by installing the Microsoft.EntityFrameworkCore.Proxies package and enabling it with a call to UseLazyLoadingProxies. Örneğin:For example:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseLazyLoadingProxies()
        .UseSqlServer(myConnectionString);

AddDbContext kullanırken:Or when using AddDbContext:

.AddDbContext<BloggingContext>(
    b => b.UseLazyLoadingProxies()
          .UseSqlServer(myConnectionString));

EF Core, geçersiz kılınabilen herhangi bir gezinti özelliği için yavaş yüklemeyi etkinleştirir-Yani, virtual ve öğesinden devralınabilen bir sınıf üzerinde olmalıdır.EF Core will then enable lazy loading for any navigation property that can be overridden--that is, it must be virtual and on a class that can be inherited from. Örneğin, aşağıdaki varlıklarda Post.Blog ve Blog.Posts Gezinti özellikleri yavaş yüklenir.For example, in the following entities, the Post.Blog and Blog.Posts navigation properties will be lazy-loaded.

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public virtual Blog Blog { get; set; }
}

Proxy olmadan yavaş yüklemeLazy loading without proxies

Yavaş yükleme proxy 'leri ILazyLoader , varlık türü oluşturucularıbölümünde açıklandığı gibi hizmeti bir varlığa ekleme.Lazy-loading proxies work by injecting the ILazyLoader service into an entity, as described in Entity Type Constructors. Örneğin:For example:

public class Blog
{
    private ICollection<Post> _posts;

    public Blog()
    {
    }

    private Blog(ILazyLoader lazyLoader)
    {
        LazyLoader = lazyLoader;
    }

    private ILazyLoader LazyLoader { get; set; }

    public int Id { get; set; }
    public string Name { get; set; }

    public ICollection<Post> Posts
    {
        get => LazyLoader.Load(this, ref _posts);
        set => _posts = value;
    }
}

public class Post
{
    private Blog _blog;

    public Post()
    {
    }

    private Post(ILazyLoader lazyLoader)
    {
        LazyLoader = lazyLoader;
    }

    private ILazyLoader LazyLoader { get; set; }

    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog
    {
        get => LazyLoader.Load(this, ref _blog);
        set => _blog = value;
    }
}

Bu, varlık türlerinin veya gezinti özelliklerinden devralınmasını gerektirmez ve ile oluşturulan varlık örneklerinin new bir içeriğe eklendikten sonra geç yükleme yapmasına izin verir.This doesn't require entity types to be inherited from or navigation properties to be virtual, and allows entity instances created with new to lazy-load once attached to a context. Ancak, ILazyLoader Microsoft. EntityFrameworkCore. soyutlamalar paketinde tanımlanan hizmete bir başvuru gerektirir.However, it requires a reference to the ILazyLoader service, which is defined in the Microsoft.EntityFrameworkCore.Abstractions package. Bu paket, buna bağlı olarak çok az etkisi olması için en az bir tür kümesi içerir.This package contains a minimal set of types so that there is very little impact in depending on it. Ancak, varlık türlerindeki tüm EF Core paketlerine bağlı olarak tamamen kaçınmak için, ILazyLoader.Load yöntemi bir temsilci olarak eklemek mümkündür.However, to completely avoid depending on any EF Core packages in the entity types, it is possible to inject the ILazyLoader.Load method as a delegate. Örneğin:For example:

public class Blog
{
    private ICollection<Post> _posts;

    public Blog()
    {
    }

    private Blog(Action<object, string> lazyLoader)
    {
        LazyLoader = lazyLoader;
    }

    private Action<object, string> LazyLoader { get; set; }

    public int Id { get; set; }
    public string Name { get; set; }

    public ICollection<Post> Posts
    {
        get => LazyLoader.Load(this, ref _posts);
        set => _posts = value;
    }
}

public class Post
{
    private Blog _blog;

    public Post()
    {
    }

    private Post(Action<object, string> lazyLoader)
    {
        LazyLoader = lazyLoader;
    }

    private Action<object, string> LazyLoader { get; set; }

    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog
    {
        get => LazyLoader.Load(this, ref _blog);
        set => _blog = value;
    }
}

Yukarıdaki kod, Load temsilciyi bir bit temizleyici kullanarak yapmak için bir genişletme yöntemi kullanır:The code above uses a Load extension method to make using the delegate a bit cleaner:

public static class PocoLoadingExtensions
{
    public static TRelated Load<TRelated>(
        this Action<object, string> loader,
        object entity,
        ref TRelated navigationField,
        [CallerMemberName] string navigationName = null)
        where TRelated : class
    {
        loader?.Invoke(entity, navigationName);

        return navigationField;
    }
}

Not

Yavaş yükleme temsilcisinin Oluşturucu parametresine "lazyLoader" adı verilmelidir.The constructor parameter for the lazy-loading delegate must be called "lazyLoader". Daha sonraki bir sürüm için bu değerden farklı bir ad kullanacak şekilde yapılandırma.Configuration to use a different name than this is planned for a future release.

EF Core, gezinti özelliklerini otomatik olarak düzeltiğinden, nesne grafiğinizde döngülerle bitilecektir.Because EF Core will automatically fix-up navigation properties, you can end up with cycles in your object graph. Örneğin, bir blog ve ilgili gönderimler yükleme, bir gönderi koleksiyonuna başvuran bir blog nesnesine neden olur.For example, loading a blog and its related posts will result in a blog object that references a collection of posts. Bu gönderilerin her birinin bloguna bir başvurusu olacaktır.Each of those posts will have a reference back to the blog.

Bazı serileştirme çerçeveleri bu tür döngülerine izin vermez.Some serialization frameworks do not allow such cycles. Örneğin, bir döngüyle karşılaşılırsa Json.NET aşağıdaki özel durumu oluşturur.For example, Json.NET will throw the following exception if a cycle is encountered.

Newtonsoft.Json.JsonSerializationException: ' MyApplication. modeller. blog ' türüne sahip ' blog ' özelliği için kendine başvuran bir döngü algılandı.Newtonsoft.Json.JsonSerializationException: Self referencing loop detected for property 'Blog' with type 'MyApplication.Models.Blog'.

ASP.NET Core kullanıyorsanız, Json.NET 'ı nesne grafiğinde bulduğu döngüleri yoksayacak şekilde yapılandırabilirsiniz.If you are using ASP.NET Core, you can configure Json.NET to ignore cycles that it finds in the object graph. Bu, ConfigureServices(...) içindeki yönteminde yapılır Startup.cs .This is done in the ConfigureServices(...) method in Startup.cs.

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );

    ...
}

Diğer bir seçenek de, bir gezinti özelliklerinden birini, [JsonIgnore] JSON.net, serileştirilirken Bu gezinti özelliğinde çapraz geçiş yapmasına yönlendiren özniteliğiyle süslemesine yönelik bir alternatiftir.Another alternative is to decorate one of the navigation properties with the [JsonIgnore] attribute, which instructs Json.NET to not traverse that navigation property while serializing.