2011-05-03 3 views
3

Ef 4.1 코드의 첫 번째 구현에 몇 가지 문제가 있습니다.EF, 코드 우선, WCF => 빈 수집 문제

public class Foo() 
{ 
    public Foo() 
    { 
     Id = Guid.NewGuid(); 
     Bars = new Collection<Bar>(); 
    } 

    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection Bars { get; set; } 
} 

public class Bar() 
{ 
    public Bar() 
    { 
     Id = Guid.NewGuid(); 
    } 

    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public virtual Foo Foo { get; set;} 
} 

public class MyContext : DbContext 
{ 
    public MyContext() 
    { 
     Configuration.ProxyCreationEnabled = false; 
    } 

    public DbSet<Foo> Foos { get; set; } 
    public DbSet<Bar> Bars { get; set; } 
} 

위의 wcf 서비스를 배치하면 빈 모음 만 반환됩니다. ProxyCreationEnabled를 켜면 컬렉션이 채워지지만 EF 프록시 생성 때문에 wcf 예외 및 연결이 끊어집니다.

제안 사항?

답변

6

바를로드하려면 열망하는로드를 사용해야합니다. EF는 관련 객체를 단독으로로드하지 않습니다. 당신은 항상 열심히 로딩 또는 게으른 로딩으로 관련 객체를 EF에 요청해야합니다. 프록시 생성을 켜면 EF는 데이터 직렬화 중에 (처음 컬렉션에 액세스 할 때) 느린 로딩으로 Bars 컬렉션을로드하려고 시도하지만 닫힌 컨텍스트 또는 일련 화 된 데이터의 순환으로 인해 예외가 발생합니다 (Bar.FooFoo.Bars주기 생성).

열망로드를 사용하려면 쿼리에 Include 방법을 추가해야합니다

:

var data = context.Foos.Include(f => f.Bars).ToList(); 

당신이 중 하나 BarFoo를 제거하거나 푸를 표시하고 IsReference=trueDataMember 속성을 DataContract와 바 있어야주기를 방지하기 위해

[DataContract(IsReference=true)] 
public class Foo() 
{ 
    public Foo() 
    { 
     Id = Guid.NewGuid(); 
     Bars = new Collection<Bar>(); 
    } 

    [DataMember] 
    public Guid Id { get; set; } 
    [DataMember] 
    public string Name { get; set; } 
    [DataMember] 
    public virtual ICollection Bars { get; set; } 
} 

[DataContract(IsReference=true)] 
public class Bar() 
{ 
    public Bar() 
    { 
     Id = Guid.NewGuid(); 
    } 

    [DataMember] 
    public Guid Id { get; set; } 
    [DataMember] 
    public string Name { get; set; } 
    [DataMember] 
    public virtual Foo Foo { get; set;} 
} 

Bar에주기를 해제하기 위해 Foo 속성을 직렬화하지 않음으로 표시해야합니다 :

public class Bar() 
{ 
    public Bar() 
    { 
     Id = Guid.NewGuid(); 
    } 

    public Guid Id { get; set; } 
    public string Name { get; set; } 
    [IgnoreDataMember] 
    public virtual Foo Foo { get; set;} 
} 
+0

답장을 보내 주셔서 감사합니다. 당신은 "EF는 결코 관련 객체를로드하지 않습니다"라고 말합니다. 위의 예 에서처럼 ProxyCreationEnabled를 켜면 관련 객체가 실제로로드됩니다. 코드 첫 번째 프레임 워크의 기능이라고 생각합니다. 여러분의 솔루션이 제대로 작동한다고해도 올바른 해결책은 아니라고 생각합니다. – HaakonL

+0

먼저 코드의 기능이 아닙니다. 그것은 게으른 로딩이라고 부르며 다시는 그 자체 없이는 트리거하지 않습니다. 개발 한 코드가 탐색 속성에 처음 액세스하면 트리거됩니다. 귀하의 경우에는 WCF 서비스에 의해 수행되는 직렬화가 될 것입니다. –

+0

Monkeyboy 11, Ladislav 66k. 말할 필요도없이 Ladislav는 꽤 정확합니다. – Stimul8d

관련 문제