2011-09-21 2 views
4

.NET MVC 3 용 포럼 프로젝트를 만들고 최신 버전의 Entity Framework로 .NET 4를 실행하고 있습니다. 엔티티 프레임 워크 4.1 코드 우선, 저장시 지연로드 참조가 필요합니다.

나는 카테고리를 가진 보드로, 일반적인 포럼 디자인을 가지고, 등 게시물

와 포럼, 주제와 포럼 및 주제와 카테고리 간체 :

public class Category { 
    [Required] 
    public virtual Board Board { get; set; } 
} 
public class Forum { 
    [Required] 
    public virtual Category Category { get; set; } 
} 
public class Topic { 
    [Required] 
    public virtual Forum Forum { get; set; } 
} 
public class Post { 
    [Required] 
    public virtual Topic Topic { get; set; } 
} 

새 게시물이 작성 될 때 주제가 통보되고 주제가 변경되면 포럼에 정보가 제공됩니다.

그래서, 다시 단순화 :

public class Forum { 
    public void TopicChanged(Topic topic) { 
     // Do stuff 
    } 
} 
public class Topic { 
    public void PostAdded(Post post) { 
     // Do stuff 
     this.Forum.TopicChanged(this); 
    } 
} 

그래서 새 게시물을 작성 (데이터베이스에 커밋) 후, 나는 부모의 주제에 PostAdded를 호출합니다. 이제 이것이 이상한 곳입니다!

리포지토리에 변경 사항을 적용하면 유효성 검사 오류가 발생하며 포럼의 범주가 필요합니다.

데이터베이스를 보면 포럼에 상위 카테고리에 대한 참조가 있습니다. 코드를 중단하고 Forum 객체를 보면 Category 인스턴스가 있습니다. 그래서 내가이 줄을 추가 할 경우, 특히 때문에, 게으른 로딩에 문제 같습니다 포럼 클래스의 TopicChanged 방법의 하단에

var cat = this.Category 

을 더 이상 오류가 없습니다.

여기서 완전히 잘못된 것을하고 있습니까? 경계선 문제가 발생 했습니까? 계속 진행되고 있습니까? 나는 EF가 레퍼런스가 게으른로드 된 레퍼런스라는 것을 알았고, 변경되지 않았다면 이것이 세이브 할 때 실패 할 이유가 없다고 생각했다.

덕분에, 스틴

+0

EF 게으른 로딩을 사용하지 않습니다. 나는 [Ladislav] (http://stackoverflow.com/users/413501/ladislav-mrnka)가 상세한 답변을했지만 기억이 안납니다. – Eranga

+0

대답은 여기에 있습니다 : http://stackoverflow.com/questions/7305144/lazy-deferred-loading-of-links-not-on-time –

+0

고맙습니다. 나는 왜 그런지 이해할 수 있지만, 그것이 내가 원하는 것을하기가 정말로 어렵게 만든다! 도청 전문가! –

답변

8

나는 내 문제를 해결했습니다. 정말 멋지고 깨끗한 해결책은 아닐지 모르겠지만 적어도 많은 코드를 변경하지 않고도이 상황을 처리 할 수 ​​있습니다 (nHibernate에서도 실행해야 함). 그래서 더러운 해결책은 없습니다.

해결 방법에 대한 아이디어 만 제공하면 여기에서 설명하겠습니다.

내 리포지토리의 Commit() 메서드에서 DbContext 인스턴스에서 GetValidationErrors()를 호출하기 시작합니다. 이 오류가 발생한 엔터티와 함께 ​​위에서 발생한 오류를 반환합니다. 이 엔티티의 기본 유형 (엔티티는 EF에 의해 생성 된 프록시 임)에서 모든 특성을 실행하고 Required 특성으로 특성을 발견하면 프록시 오브젝트의 동일한 특성에 대해 GetValue를 호출합니다.

충분히 이야기, 더 많은 코드 : 그것의 유효성을 검사 할 때

var errors = this.context.GetValidationErrors(); 
foreach (DbEntityValidationResult result in errors) { 
    Type baseType = result.Entry.Entity.GetType().BaseType; 
    foreach (PropertyInfo property in result.Entry.Entity.GetType().GetProperties()) { 
     if (baseType.GetProperty(property.Name).GetCustomAttributes(typeof(RequiredAttribute), true).Any()) { 
      property.GetValue(result.Entry.Entity, null); 
     } 
    } 
} 
+1

당신은 천재입니다. – friism

관련 문제