2016-07-24 3 views
10

ef core와 관련하여 게임을했는데 include 문과 관련된 문제가있었습니다. 이 코드를 위해 나는 내가 예상했던 2 개의 회사를 얻는다.Entity Framework 핵심 .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}] 

를 반환하면이 두 회사는 내가 어떤 내가 기대했던 인이 포함되어 사용 havnt 모든 관련 속성이 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}] 
}] 

그것은 단지 한 회사를 반환하고 단지 관리자가 포함되어 있습니다. 왜 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 만 사용했을 가능성은 충분히 있지만 동의하지 않습니다. 분명히 serializer 참조 루프 처리 문제처럼 보이지만 출력을 표시하기 위해 JSON을 사용하기 때문에 이런 식으로 보일 수 있습니다. 다운 페이징 (downvoting) 전의 상황인지 여부를 OP 상태로 알려주지 않는 이유는 무엇입니까? –

+0

Accutaly이 문제를 해결하는 방법입니다. 고마워요! – 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

use 로딩 메소드가 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; 
     } 

도움이되면 기쁠 것입니다. 프로덕션 준비 코드가 아닙니다.

관련 문제