【问题标题】:.net core 2.0 entity framework infinite nested entities [duplicate].net core 2.0实体框架无限嵌套实体[重复]
【发布时间】:2018-03-06 21:25:54
【问题描述】:

我遇到了实体框架问题,包括所有冗余的嵌套实体以及那些实体,包括已经加载的实体,然后这些实体加载相同的嵌套实体等。

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

问题:如何防止 Clients 属性提取其客户列表?目前,我已使用 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();

【问题讨论】:

  • 你不知道为什么这对你来说是个问题,但我猜它与this有关。如果是这样,请认为这是重复的。
  • 我刚刚发布了代码,这就产生了问题。如果这很重要,我使用的是 postgresql 而不是 ms sql
  • 再说一次,为什么这是个问题?实体是相互关联的。那又怎样?
  • 我猜我发现它是一个循环引用,我可能只是删除另一个实体上的一个属性来解决这个问题。
  • 嗯,你看我的第一条评论和里面的链接了吗?

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


【解决方案1】:

关闭更改跟踪。

跟踪行为控制 Entity Framework Core 是否将有关实体实例的信息保留在其更改跟踪器中。如果一个实体被跟踪,那么在实体中检测到的任何更改都将在 SaveChanges() 期间持久保存到数据库中。 Entity Framework Core 还将修复从跟踪查询获得的实体与之前加载到 DbContext 实例中的实体之间的导航属性。

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

EG

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

【讨论】:

  • 您的测试与 OP 的代码有本质的不同。用Include 尝试同样的事情,你会得到其他结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-15
  • 2018-01-27
  • 1970-01-01
  • 2010-10-24
相关资源
最近更新 更多