2017-09-25 99 views
2

我有一個實體框架的問題,包括所有的冗餘嵌套實體和那些實體,包括已經加載的實體,然後這些實體加載相同的嵌套實體等。.net core 2.0實體框架無限嵌套實體

情況:我有一個包含很多客戶端列表的客戶端列表。

問題:如何防止客戶端屬性拉取他們的客戶端列表?目前我擁有所有使用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(); 
+2

你不告訴*爲什麼*這是你的一個問題,但我想這是關係到[這] (https://stackoverflow.com/q/19467673/861716)。如果是這樣,請認爲這是重複的。 –

+0

我剛剛發佈的代碼,這是產生問題。我使用postgresql而不是ms sql,如果這很重要 – Rami

+1

再次,*爲什麼*這是一個問題?這些實體是相互關聯的。所以呢? –

回答

0

關閉更改跟蹤。

跟蹤行爲控制實體框架的核心是否會保留有關其變化跟蹤實體實例信息。如果對實體進行跟蹤,則在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 
+1

您的測試與OP的代碼基本上不同。用'Include'嘗試同樣的事情,你會得到其他結果。 –