2017-09-25 17 views
2

冗長なネストされたエンティティをすべて含むエンティティフレームワークに問題があります。すでにロードされているエンティティを含むエンティティを含み、それらのエンティティは同じネストエンティティなどをロードします。.netコア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

私はちょうどコードを掲示し、これは問題を作り出しています。問題がある場合、私はmsqlではなくpostgresqlを使用しています – Rami

+1

もう一度、*なぜ*これは問題ですか?エンティティは相互に接続されています。だから何? –

答えて

0

変更トラッキングをオフにします。

は、Entity Frameworkのコアは、その変更トラッカ内のエンティティのインスタンスに関する情報を保持するかどうかを

追跡行動のコントロールを参照してください。エンティティが追跡される場合、エンティティで検出された変更はすべて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 
+1

あなたのテストは基本的にOPのコードとは異なります。 'Include'で同じことを試してみると、他の結果が得られます。 –

関連する問題