c# - .net core 2.0 Entity Framework 无限嵌套实体

标签 c# entity-framework asp.net-core-2.0

<分区>

我在 Entity Framework 方面遇到问题,包括所有冗余的嵌套实体和那些实体,包括已经加载的实体,然后这些实体加载相同的嵌套实体等。

情况:我有一个客户列表,其中有很多包含也有客户列表。

问题:如何防止客户属性提取他们的客户列表?目前我已使用 Virtual 关键字设置了所有实体,但它们仍被包括在内。

public IEnumerable<Property> GetProperties()
    {
        return _context.Property.AsQueryable()
            .Include(x => x.PropertyType).AsNoTracking()
            .Include(x => x.PropertyStatus).AsNoTracking()
            .Include(x => x.EngagementType).AsNoTracking()
            .Include(x => x.IntInvestorClient).AsNoTracking()
            .Include(x => x.PropertySizeType).AsNoTracking()
            .Include(x => x.Division).AsNoTracking()
            .Include(x => x.LocalMarketArea).AsNoTracking()
            .Include(x => x.Country).AsNoTracking();
    }

var all = _repo.GetProperties();

        var result = returnAll ? all.ToList() : all.Skip(offset).Take(limit).ToList();

最佳答案

关闭更改跟踪。

Tracking behavior controls whether or not Entity Framework Core will keep information about an entity instance in its change tracker. If an entity is tracked, any changes detected in the entity will be persisted to the database during SaveChanges(). Entity Framework Core will also fix-up navigation properties between entities that are obtained from a tracking query and entities that were previously loaded into the DbContext instance.

https://learn.microsoft.com/en-us/ef/core/querying/tracking

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;

namespace EFCore2Test
{

    public class Note
    {
        public int Id { get; set; }
        public string Value { get; set; }
    }

    public class Item
    {
        public int Id { get; set; }

        public string Name { get; set; }
    }
    public class Part
    {
        public int Id { get; set; }
        public ICollection<Part> ChildParts { get; } = new HashSet<Part>();

        public ICollection<Note> Notes { get; } = new HashSet<Note>();

        public int? ItemId { get; set; }
        public Item Item { get; set; }
    }

    public class Db : DbContext
    {
        public DbSet<Part> Parts { get; set; }
        public DbSet<Item> Items { get; set; }
        public DbSet<Note> Notes { get; set; }


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            base.OnModelCreating(modelBuilder);
        }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Server=(local);Database=EfCoreTest;Trusted_Connection=True;MultipleActiveResultSets=true");
            base.OnConfiguring(optionsBuilder);
        }
    }




    class Program
    {


        static void Main(string[] args)
        {

            int partid;
            using (var db = new Db())
            {
                db.Database.EnsureDeleted();
                db.Database.EnsureCreated();

                var item = new Item();
                db.Items.Add(item);

                var p = new Part();
                p.Item = item;

                for (int i = 0; i < 10; i++)
                {
                    var cp = new Part();
                    p.ChildParts.Add(cp);
                    db.Parts.Add(cp);

                }

                for (int i = 0; i < 4; i++)
                {
                    p.Notes.Add(new Note() { Value = "Note" });
                }

                db.Parts.Add(p);

                db.SaveChanges();
                partid = p.Id;
            }


            using (var db = new Db())
            {
                Console.WriteLine("With Change Tracking");

                var q = from p in db.Parts
                                    .Include(p => p.Notes)
                                    .Include(p => p.Item)
                        orderby p.Id == partid?0:1, p.Id
                        select p;

                var parts = q.Take(5).ToList();

                foreach (var p in parts)
                {
                    Console.WriteLine($"Part {p.Id}, Child Parts {p.ChildParts.Count}");

                }
                Console.WriteLine();
            }


            using (var db = new Db())
            {
                Console.WriteLine("Without Change Tracking");

                var q = from p in db.Parts.AsNoTracking()
                                     .Include(p => p.Notes)
                                     .Include(p => p.Item)
                        orderby p.Id == partid ? 0 : 1, p.Id
                        select p;

                var parts = q.Take(5).ToList();

                foreach (var p in parts)
                {
                    Console.WriteLine($"Part {p.Id}, Child Parts {p.ChildParts.Count}");

                }
            }
            Console.WriteLine("Hit any key to exit");
            Console.ReadKey();
        }
    }
}

输出

With Change Tracking
Part 1, Child Parts 4
Part 2, Child Parts 0
Part 3, Child Parts 0
Part 4, Child Parts 0
Part 5, Child Parts 0

Without Change Tracking
Part 1, Child Parts 0
Part 2, Child Parts 0
Part 3, Child Parts 0
Part 4, Child Parts 0
Part 5, Child Parts 0
Hit any key to exit

关于c# - .net core 2.0 Entity Framework 无限嵌套实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46413166/

相关文章:

c# - 使用 Entity Framework 的右外连接

c# - 当使用 MVVM 更改一行 DataGrid 时将更改应用于模型

c# - 文本框.SelectionStart

entity-framework - Entity Framework 服务层更新 POCO

c# - EntityFramework 代码首先是 : Set order of fields

c# - asp.net core 2 - 特定领域的自定义模型绑定(bind)

c# - 如何用 C# 实现 Web 服务

c# - 如何将 C# 类公开为 com 对象接口(interface)?

asp.net-mvc - Asp.net core 2中View和Page有什么区别?

c# - 如何存储/检索大量用户身份声明