2011-12-01 4 views
2

EF 코드 4.1을 사용하는 데 문제가 있습니다. 뭔가 이해하지 못하고 있습니다.게으른 로딩이 작동하지 않습니다.

나의 이해는 가상으로 (컬렉션 또는 단일 개체 여부), 그들은 수요에로드 게으른 것, 그래서 같은 것을 할 수있는 관계를 표시하여 :

var page = context.Pages.Where(xxxx); 

var department = page.Department; //load this on demand? 
var name = department.Name; //null reference exception 

page.DepartmentId가 제대로 설치되어, 하나. 또한, 참조를 context.Entry (page) .Reference (p => p.Department) .Load()와 함께 참조를 수동으로로드하지만, 객체 모델을 갖는 전체 요점은 모든 곳에서 강박 적으로 그렇게 할 필요가 없다는 것입니다.

public class Page 
{ 
    public int DepartmentId { get; set; } 
    public virtual Department { get; set; } 
} 

public class Department 
{ 
    public virtual ICollection<Page> Pages { get; set; } 
} 

상황 OnModelCreating

modelBuilder.Entity<Page>().HasRequired(x => x.Department).WithMany(y => y.Pages).HasForeignKey(x => x.DepartmentId).WillCascadeOnDelete(false); 

나는 물론, 장애인 게으른 로딩을하지했습니다.

+0

부서의 식별자는 무엇입니까? –

답변

4

프로젝트의 일부 위치에 문제가있을 수 있습니다. 나는 당신의 조각을 기반으로 간단한 응용 프로그램을 만들었고 모든 것이 잘 작동합니다. 시도하고 다른 것을 확인하십시오.

첫째, 내 간단한 상황 : 이제 테스트를

public class Page 
{ 
    public int ID { get; set; } 
    public int DepartmentId { get; set; } 
    public virtual Department Department { get; set; } 
} 

public class Department 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<Page> Pages { get; set; } 
} 

:

class TestInit : DropCreateDatabaseAlways<MyContext> 
{ 
    protected override void Seed(MyContext context) 
    { 
     base.Seed(context); 

     var newDepartment = context.Departments.Create(); 
     newDepartment.Name = "test"; 
     context.Departments.Add(newDepartment); 

     var newPage = context.Pages.Create(); 
     newPage.Department = newDepartment; 
     context.Pages.Add(newPage); 

     context.SaveChanges(); 

     // leaving nothing in context 
     var fullContext = (context as IObjectContextAdapter).ObjectContext; 
     fullContext.Detach(newDepartment); 
     fullContext.Detach(newPage); 
    } 
} 

그리고 당신의 클래스를 :

class MyContext : DbContext 
{ 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<Page>().HasRequired(x => x.Department).WithMany(y => y.Pages).HasForeignKey(x => x.DepartmentId).WillCascadeOnDelete(false); 
    } 

    public IDbSet<Page> Pages { get; set; } 
    public IDbSet<Department> Departments { get; set; } 
} 

은 거의 더미 초기화가 데이터베이스에 일부 데이터를 넣어 Database.SetInitializer (새 TestInit()); 당신은 볼 수

using (MyContext context = new MyContext()) 
{ 
    Console.WriteLine(context.Pages.Local.Count); 
    Console.WriteLine(context.Departments.Local.Count); 

    var page = context.Pages.First(); 
    Console.WriteLine(page.GetType().FullName); 
    Console.WriteLine(page.Department.Name); 
} 

은 (프록시 해시 아마 약간 다를 수 있습니다) :

0 
0 
System.Data.Entity.DynamicProxies.Page_6D31E91F3B1E767826A19855D3A934B59F85AC161548E4761283C85824520E1D 
test 

처음 두 제로 맥락에서 어떤 실체가 없다는 것을 확신이 있어야한다. Page 클래스의 유형은 프록시 여야하며, 프로그램 자체의 유형 인 경우 프록시가 생성되지 않습니다. 아마도 꺼져 있거나 뭔가 가상하지 않습니다. 마지막 줄은 부서의 실제 이름입니다.

나는 또한 다른 쿼리 외에 프로그램을 실행할 때 :

SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[Name] AS [Name] 
FROM [dbo].[Departments] AS [Extent1] 
WHERE [Extent1].[ID] = @EntityKeyValue1 

가 데이터베이스로 전송됩니다. 그것은 당신이 부서에 대한 변수를 누락

public class Page 
{ 
    public int DepartmentId { get; set; } 
    public virtual Department Department { get; set; } 
} 

을 도움이된다면

0

는 페이지에 대한 다음과 같은 모델을 시도하고 참조하십시오. 그것이 지금 일하기를 바란다

1

나는 나의 상황에서 무엇이 잘못되었는지에 관해 알았다. 기본 생성자를 private로 표시하여 ef가 프록시를 생성하지 못했습니다.

모두에게 감사드립니다.

관련 문제