현재 레코드가없는 경우 MVC DBContext 상위 레코드 찾기
-
11-12-2019 - |
문제
저는 MVC / C # 초보자이므로 쉽게 가십시오.
고객이 제로 또는 많은 프로젝트가있는 기존 데이터베이스가 있습니다. ADODB 엔티티 데이터 모델 및 DBContext 코드 생성기에서 ASP.NET 프로젝트를 만들었습니다.
고객이 있습니다 : Joe Bloggs (ID= 7). 나는 그의 프로젝트를 볼 수 있도록 조 양식의 Joe Bloggs의 '프로젝트'링크를 클릭합니다. 그는 아무 것도 없어. 프로젝트 컨트롤러에서 프로젝트를 만들어 프로젝트를 만들고 싶습니다.
조인 블로그 ID를 세 가지 이유로 작성 조치에 전달해야합니다 (필요하지 않을 수 있습니다 - 필요할 경우 나를 계몽하십시오)
-
Joe Bloggs 프로젝트이기 때문에 Create View 모델 데이터를 생성 할 때 기본 고객 ID를 설정할 수 있도록 Controller에 ID= 7을 통과 할 수 있습니다.
Create View에서 취소 버튼을 누르면 Joe Blogs 를 기반으로하는 프로젝트의 원래 필터링 된보기로 돌아 가려고합니다.
-
저장을 누르면 Joe Bloggs를 기반으로하는 프로젝트의 원래 필터링 된보기로 돌아 가려고합니다. 은 Joe Blogg에 대한 하나 이상의 프로젝트를 가지고 있다면 아래의 모델 데이터 에서이 괴물을 사용할 수 있습니다.
.<input type="button" title = "New Project" value="New Project" onclick="location.href='@Url.Action("Create", new { id = Model.First().Customer_ID })'" />
여기 문제가 있습니다. 그가 프로젝트가없는 경우 model.first ()는 '상위'customer_id 레코드를 찾을 수 없도록 아무 것도 반환하지 않습니다.
DBContext를 사용하여 모델 클래스를 생성했습니다 (이것은 데이터 첫 번째 개발입니다). 뭔가가 이러한 클래스를 확장하거나 위의 경우를 허용 할 수있는 새 클래스를 만들 수 있습니다.
내 현재의 해결 방법은 ViewBag를 사용하여 뷰어에서 다양한 ID와 문자열을 전달하는 것입니다. 핫 감자처럼 컨트롤러> 3 개의 깊이 (고객> Proejct> 작업)를 얻는 경우에는 고객 이름을 표시하고 싶습니다. 과제, 나는 그것을 두 번 통과 시켰습니다. 냄새가납니다.
프로젝트 인덱스 뷰에서 드롭 다운이 은 고객이 에 있습니다. 다음은 그 코드입니다.
.@Html.DropDownList("Customer_ID", null, "Select a Customer to Filter", new { @onchange = "this.form.submit();" })
나는 그것을 거기에서 해킹 할 수 있지만 실제로 나는이 드롭 다운에서 2 ~ 3 깊이에서 멀리 떨어져있는 수업에서 횡단 할 수 있기를 원한다
다음은 dbContext 에서 생성 된 abridged 고객 및 customerProject 클래스입니다
.public partial class Customer { public Customer() { this.Tasks = new HashSet<Task>(); this.CustomerProjects = new HashSet<CustomerProject>(); } public int Customer_ID { get; set; } public string Customer_Name { get; set; } public virtual ICollection<CustomerProject> CustomerProjects { get; set; } } public partial class CustomerProject { public CustomerProject() { this.Tasks = new HashSet<Task>(); this.CustomerProjectTasks = new HashSet<CustomerProjectTask>(); } public int CustomerProject_ID { get; set; } public int Customer_ID { get; set; } public string Project_Name { get; set; } public virtual ICollection<Task> Tasks { get; set; } public virtual Customer Customer { get; set; } public virtual ICollection<CustomerProjectTask> CustomerProjectTasks { get; set; } }
나는 분명한 솔루션이 있지만 강점이 데이터베이스와 VB6에 있고, C # / p>가 아닌
Mystere Man의 제안에서는 ViewModel 클래스를 만들었지 만 약간의 문제가 있습니다.
여기서는 내 모델 클래스 파일에있는 것입니다 (기존 프로젝트 엔티티 주위의 래퍼 일뿐입니다.) :
.namespace zzz.Models { using System; using System.Collections.Generic; public class ProjectsViewModel { public int Customer_ID { get; set; } public ICollection<CustomerProject> CustomerProjects; } }
여기서 내 컨트롤러의 인덱스 조치에 뭔지가 뭐가 있습니다 (기존 프로젝트 컬렉션을 새로운 뷰 헬드 클래스에 추가) :
.public ViewResult Index(int pCustomer_ID = 0, string pProjectName_Filter = "") { // Set up drop down ViewBag.Customer_ID = new SelectList(db.Customers.OrderBy(x => x.Customer_Name), "Customer_ID", "Customer_Name"); //ViewBag.Selected_Customer_ID = Customer_ID; // If no parameters entered, show nothing // Otherwise optionally filter each parameter var projects = from p in db.CustomerProjects orderby p.Active, p.Project_Order where (p.Project_Name.Contains(pProjectName_Filter) || pProjectName_Filter.Equals("")) && (p.Customer_ID == pCustomer_ID || pCustomer_ID.Equals(0)) && !(pCustomer_ID.Equals(0) && pProjectName_Filter.Equals("")) select p; var customerprojects = new ProjectsViewModel { Customer_ID = pCustomer_ID, CustomerProjects = projects.ToList() }; return View(customerprojects); }
여기에서 추출물이 내 뷰에서 추출됩니다 (뷰 모드 클래스 내의 프로젝트 컬렉션을 반복하려고 시도) :
.@model IEnumerable<BistechPortal.Models.ProjectsViewModel> <table> @foreach (var item in Model.CustomerProjects) { <tr> <td> @Html.DisplayFor(modelItem => item.Project_Name) </td> </tr> } </table>
인덱스 작업을 실행할 때 foreach line에서 i :
.'System.Collections.Generic.IEnumerable<zzzzPortal.Models.ProjectsViewModel>' does not contain a definition for 'CustomerProjects' "
번역 해주세요 - 왜 내 뷰어 모델에서 내 'CustomerProjects'컬렉션을 찾을 수 없습니까?
해결책
엔티티 객체를 직접 뷰에 전달해서는 안됩니다.대부분의 경우 뷰는 정의 된 엔티티가 제공하는 것보다 많은 정보 (또는 다른 정보)가 필요합니다.
View 모델이 존재하는 이유입니다.customer_id와 프로젝트 (및 필요한 다른 데이터)가 들어있는보기 모델을 만듭니다.그런 다음 사용자가 프로젝트가없는 경우에도 CUSTAME_ID에 액세스 할 수 있습니다.
public class ProjectsViewModel {
public int Customer_ID {get;set;}
public List<CustomerProject> CustomerProjects;
}
.
이 새 개체를보기에 전달합니다.
(OP :)
이 객체를보기에 전달하여 더 이상 CustomerProjects 유형의 데이터를 더 이상 받아들이는 것이 더 이상이 아니라는 데 3 시간이 걸렸습니다.'열거 가능'데이터 가져 오기.
그래서 귀하의 견해 변경
.
@model IEnumerable<Portal.Models.CustomerProjects>
~
.
@model Portal.Models.ProjectsViewModel
또한 이제 model.customerProject를 통해 반복하려는
.
@foreach (var item in Model)
~
.@foreach (var item in Model.CustomerProjects)