2011-03-27 5 views
2

, 나는초급 EF4/CodeFirst/MVC3 도움

내가 생각 굉장이 두 자습서를 사용하고 도움이 그것을 투쟁을 찾는 필요 해요 : http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx

현재 내 주요 문제/혼란은 http://msdn.microsoft.com/en-us/data/gg685467 :

내가 제대로 얻는 방법을 모르는 CodeFirst 테이블/엔티티가 다른 테이블/엔티티의 데이터를 내보기에 표시 :

0 나는 (목록 형/옵션을 사용하여) 자동차에 대한보기를 만들 때
public class Car { 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public int EngineID { get; set; } 
    public virtual Engine { get; set; } 
} 

public class Engine { 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Manufacturer { get; set; } 
    // (plus a whole lot of other things) 
} 

는 지금은 engineID를 제외하고

@foreach (var item in Model) { 
<tr> 
    <td>@item.ID</td> 
    <td>@item.Name</td> 
    <td>@item.EngineID</td> 
</tr> 

완벽한 ... 뷰어에 대부분 쓸모있는 좋은 자동 생성 된 목록을 얻고, 내가 원하는 Engine.Name을 표시하는 대신

그래서 내가 EF 게으른 로딩 사용할 수 있습니다 가정 : 불행하게도 나는 것을 시도 할 때

<td>@item.Engine.Name</td> 

을, 내 ObjectContext는이 B를 가지고 말한다 EEN은 더 이상 데이터가 내가 컨트롤러에가는 시도 연결 그리고

을 필요로하고 저를 알려주는 Engine.Name

var cars = (from c in db.Cars.Include("Engine.Name") select c; 

을 포함하지 수 있도록 배치 : Entities.Engine은 탐색 속성을 선언하지 않습니다 이름이 '012' '이름'

...?

가 포함 거짓말 ("엔진") 잘 작동하지만 내가 원하는 모든 이름이며, ("엔진")는 이전 상황과 같은에서 내가

을 원하지 않는 것들의 많은 양의로드 포함 이 EngineName뿐만 아니라 자동차에 대한 DB에서 뷰를 만들었습니다. 그러나 CodeFirst와 나의 고결함으로 나는 이것을 할 수있는 방법을 찾지 못했습니다.

이 문제를 어떻게 해결해야합니까?

저는 Car 엔티티와 거의 같은 모델을 만들 수 있다고 생각했지만 Engine.Name을 추가했습니다. 이것은 내가 다음 여러 위치에 다시 사용할 수 있기 때문에 좋은 것입니다,하지만 난 그것을 위 등

뿐만 아니라 TDD를 배우고 싶은

하지만를 채우는 방법에 딱하다는 이미 저를 실망 : P

시를 다른 튜토리얼 링크 또는 읽을 수있는 편리한 것들이 크게 평가 될 것입니다.

답변

2

실제로는 탐색 할 수있는 방법을 제공하는 2 차 레벨 아래쪽 속성 인 속성을 포함하려고 시도하는 것은 거짓말이 아닙니다. EF가이 구조로 DB를 생성하게하면, Car_Engine과 같은 네비게이션 테이블을 만들었을 것이고, 네가 매핑 한 객체없이 이름을 포함하면 새로운 객체에 네비게이션 속성이 생기지 않을 것입니다.당신은 아직도 당신이 제대로 스키마에 매핑되어 있는지 확인해야 할 수도 있습니다 탐색 속성 오류를 얻을 경우

(from c in db.Cars.Include("Engine") select new { c, EngineName = c.Engine.Name } 

을 :

이 주변의 간단한 방법은 이동하는 것입니다. Fluent API를 사용하는 EntityTypeConfiguration 클래스를 사용하여이 작업을 수행 할 수 있습니다. 매우 강력합니다.

물론 이것은 MVC에 표시 할 자동차 객체를 강력하게 입력하는 데 도움이되지 않습니다. 이 문제를 해결하려면 직감이 옳다. 데이터의 간단한 뷰를 제공하는 읽기 전용 (디자인에 따라, 반드시 읽기 전용으로 설정된 것은 아님) 클래스 인 뷰 모델을 사용하는 것이 일반적입니다.

필자는 개인적으로 모델을 매우 깨끗하게 유지 한 다음 다른 모델의 뷰 모델과 프리젠 테이션 프로젝트로 채 웁니다. 나는 당신의 핵심 모델에서 중복되는 엔티티를 사용하는 것을 피할 것입니다. 왜냐하면 데이터 컨텍스트에서 예기치 않은 동작을 일으킬 수 있고 여러 엔티티를 업데이트 할 때 (예 : 엔진 이름을 누가 업데이트해야합니까?) 적어도 불안정한 악몽을 불러 일으킬 수 있기 때문입니다.

viewmodels를 사용하면 CarSummaryView라는 클래스 또는 원하는 데이터 만있는 클래스를 만들 수 있습니다. 또한 사이트에서 과도하게 지나치는 곳이나 과소 평가에 취약한 문제를 해결합니다. 그것은 위의 쿼리로 아주 쉽게 채워질 수 있습니다.

추 신 전체 heirarchies를로드하지 않고 뷰 모델을 사용하면 많은 이점이 있습니다. 가장 큰 것 중 하나는 과도기 및 과소 시나리오를 피하는 데있어서 발생하는 본질적인 이점입니다.

이 viewmodels을 구현하는 방법의 부하하지만 간단한 CarView의 예로서 :

public class CarView 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string EngineName { get; set; } 
} 

이 명확 엔터티 모델 구분되어야한다. 큰 프로젝트에서는 발표자가 반환 할 수있는 단일보기 모델 프로젝트가 있지만, 작은 프로젝트에서는 서비스 코드와 동일한 레이어에 있어야합니다.

쿼리에서 직접 채우려면, 당신은이

List<CarView> cars = (from c in db.Cars.Include("Engine.Name") select new CarView() { ID = c.ID, Name = c.Name, EngineName = c.Engine.Name }).ToList(); 
+0

당신이 나에게 CarSummaryView의 뷰 모델의 빠른 예를 들어 줄 수 있을까 다음 할 수있는 방법을 채우는 데? 또한 EngineName = e.Name의 e는 무엇입니까? 당신이 모든 일을 할 수있게하려는 것이 아니라, 내 머리 속에서 연결되어 이해가 안되는 것일뿐입니다. – mejobloggs

+0

간단한 예제가 제공되었습니다. 전자는 실수 였어. 지금 편집 했어. – Gats

+0

정말 고마워. 또한, 새 CarView()를 선택하면 .Include ("Engine.Name")을 사용할 필요조차 없다는 것을 알 수 있습니다 (지연로드가 해제 된 경우는 예외). – mejobloggs