.net core 2.0实体框架无限嵌套实体

时间:2017-09-25 19:54:00

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

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

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

问题:如何阻止客户端属性'从拉客户名单?目前,我使用虚拟关键字设置了所有实体,但它们仍然被包含在内。

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();

1 个答案:

答案 0 :(得分:0)

关闭更改跟踪。

  

跟踪行为控制Entity Framework Core是否会在其更改跟踪器中保留有关实体实例的信息。如果跟踪实体,则在SaveChanges()期间,实体中检测到的任何更改都将持久保存到数据库。 实体框架核心还将修复从跟踪查询获取的实体与先前加载到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