2016-07-24 12 views
10

efコアに関する演奏をしていて、インクルードステートメントに問題がありました。このコードでは、私は2つの企業を得ました。これは私が期待したものです。あなたがそこに2社があり、私はどんな私が期待したものである、含まれる使用havntとして、関連するすべてのプロパティがnullで見ることができるようにエンティティフレームワークのコア.Include()の問題

public IEnumerable<Company> GetAllCompanies(HsDbContext db) 
{ 
    var c = db.Company; 
    return c; 
} 

これは

[{"id":1,"companyName":"new","admins":null,"employees":null,"courses":null}, 
{"id":2,"companyName":"Test Company","admins":null,"employees":null,"courses":null}] 

を返します。今、私はこれにメソッドを更新するとき:

public IEnumerable<Company> GetAllCompanies(HsDbContext db) 
{ 
    var c = db.Company 
     .Include(t => t.Employees) 
     .Include(t => t.Admins) 
     .ToList(); 

    return c; 
} 

これは、それが返すものです:

[{"id":1,"companyName":"new", 
    "admins":[{"id":2,"forename":"User","surname":"1","companyId":1}] 
}] 

それは1社のみを返し、管理者のみが含まれています。なぜ2社と従業員が含まれていないのですか?

public class Company 
{ 
    public int Id { get; set; } 
    public string CompanyName { get; set; } 
    public List<Admin> Admins { get; set; } 
    public List<Employee> Employees { get; set; } 
    public List<Course> Courses { get; set; } 

    public string GetFullName() 
    { 
     return CompanyName; 
    } 
} 

public class Employee 
{ 
    public int Id { get; set; } 
    public string Forename { get; set; } 
    public string Surname { get; set; } 
    public int CompanyId { get; set; } 
    [ForeignKey("CompanyId")] 
    public Company company { get; set; } 

    public ICollection<EmployeeCourse> Employeecourses { get; set; } 
} 


public class Admin 
{ 
    public int Id { get; set; } 
    public string Forename { get; set; } 
    public string Surname { get; set; } 
    public int CompanyId { get; set; } 
    [ForeignKey("CompanyId")] 
    public Company Company { get; set; } 
} 
+0

EF 6以下で同じコードを試しましたか? –

+0

あなたのEFバージョンは何ですか? – Mafii

+1

@Mafii、それはEF Core - EF 7です、タイトル –

答えて

9

あなたはこのquestionに受け入れ答えを見てきた場合、私はわからないんだけど、問題はJSONシリアライザは、循環参照を扱う方法で行うことです。複数の参照への完全な詳細とリンクは上記のリンクで見つけることができます、と私はそれらを掘り下げることをお勧めしたいが、簡単に言えば、startup.csに以下を追加すると、循環参照を無視するシリアライザを設定します:

services.AddMvc() 
    .AddJsonOptions(options => { 
     options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 
    }); 
+1

この問題はJSONとは関係ありません。 – Langdon

+0

@JohnMorrisonは出力を表現する便利な方法としてJSONだけを使用していた可能性はありますが、私は同意しません。確かに、シリアライザのリファレンスループ処理の問題のように見えますが、出力を表示するためにJSONを使用するため、このように見えます。なぜそれがdownvoting前のケースかどうか、OPの状態を聞かせてください? –

+0

これはこれを修正する方法です。どうもありがとう! – LaPuyaLoca

1

私はあなたのコードをテストします。この問題は私のテストにあります。この投稿ではLINKを使用してデータ投影を使用することを提案しました。あなたの問題のために次のようなものは仕事です。

[HttpGet] 
public dynamic Get() 
{ 
    var dbContext = new ApplicationContext(); 

    var result = dbContext.Companies 
     .Select(e => new { e.CompanyName, e.Id, e.Employees, e.Admins }) 
     .ToList(); 

    return result; 
} 
+0

この方法でうまくいきます。ありがとう。だから、エンティティ・フレームワークでの遅延読み込みの問題があると思いますか? –

+0

インクルードの読み込みメソッドがeagerloadingで、データが最初のクエリで読み込まれる場合 –

0

レイジーEFコアではまだロードできません。 Refer here

また、eager loadingを使用することもできます。

以下は、このarticle

を読むには、私は熱心なロードを達成するために作成した拡張メソッドです。

拡張メソッド:

public static IQueryable<TEntity> IncludeMultiple<TEntity, TProperty>(
      this IQueryable<TEntity> source, 
      List<Expression<Func<TEntity, TProperty>>> navigationPropertyPath) where TEntity : class 
     { 
      foreach (var navExpression in navigationPropertyPath) 
      { 
       source= source.Include(navExpression); 
      } 
      return source.AsQueryable(); 
     } 

リポジトリコール:

public async Task<TEntity> FindOne(ISpecification<TEntity> spec) 
     { 
      return await Task.Run(() => Context.Set<TEntity>().AsQueryable().IncludeMultiple(spec.IncludeExpression()).Where(spec.IsSatisfiedBy).FirstOrDefault()); 
     } 

使用法:

List<object> nestedObjects = new List<object> {new Rules()}; 

      ISpecification<Blog> blogSpec = new BlogSpec(blogId, nestedObjects); 

      var challenge = await this._blogRepository.FindOne(blogSpec); 

依存性:

public class BlogSpec : SpecificationBase<Blog> 
    { 
     readonly int _blogId; 
     private readonly List<object> _nestedObjects; 

     public ChallengeSpec(int blogid, List<object> nestedObjects) 
     { 
      this._blogId = blogid; 
      _nestedObjects = nestedObjects; 
     } 

     public override Expression<Func<Challenge, bool>> SpecExpression 
     { 
      get { return blogSpec => blogSpec.Id == this._blogId; } 
     } 

     public override List<Expression<Func<Blog, object>>> IncludeExpression() 
     { 
      List<Expression<Func<Blog, object>>> tobeIncluded = new List<Expression<Func<Blog, object>>>(); 
      if (_nestedObjects != null) 
       foreach (var nestedObject in _nestedObjects) 
       { 
        if (nestedObject is Rules) 
        { 
         Expression<Func<Blog, object>> expr = blog => blog.Rules; 
         tobeIncluded.Add(expr); 
        } 

       } 

      return tobeIncluded; 
     } 

助けてくれたらうれしいです。これは実稼働可能なコードではありませんのでご注意ください。

関連する問題