我遇到了实体框架的问题,包括所有冗余的嵌套实体和那些已经加载的实体,然后这些实体加载相同的嵌套实体等。
情况:我有一个包含很多包含客户列表的客户列表。
问题:如何阻止客户端属性'从拉客户名单?目前,我使用虚拟关键字设置了所有实体,但它们仍然被包含在内。
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();
答案 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