2016-08-16 2 views
3

데이터 모델을 설정하는 방법을 모르겠습니다.Model 또는 viewModel에 "필수"데이터 주석을 추가해야합니까?

내가 사용 : MVC 5, EF 6.1.3

나는 몇 가지 속성을 가진 모델 클래스 (몇 가지 "필수"데이터 주석 장식 만든 데이터베이스 테이블에 반영하기 위해 속성)이, 해당 필드는 내 컨트롤러에서 viewModel을 사용하여 채워집니다.

[HttpPost] 
public ActionResult Create(CreateRequestViewModel viewModel) 
{ 
    if (!ModelState.IsValid) 
    { 
     viewModel.Affiliations = _context.Affiliations.ToList(); 
     viewModel.Issues = _context.Issues.ToList(); 
     return View(viewModel); 
    } 

    var request = new Request 
    { 
     RequestDate = DateTime.Today, 
     Status = "Open", 
     FirstName = viewModel.FirstName, 
     LastName = viewModel.LastName, 
     AffiliationId = viewModel.Affiliation, 
     IssueId = viewModel.Issue, 
     LastModificationDate = DateTime.Now, 
     RequestTypeId = 2, 
    }; 

    _context.Requests.Add(request); 
    _context.SaveChanges(); 

    return View("Success"); 
} 

모델 클래스 :

public class Request 
{ 
    [Display(Name = "Request ID")] 
    public int Id { get; set; } 

    [Required] 
    [Display(Name = "Request Date")] 
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] 
    public DateTime RequestDate { get; set; } 

    [Required] 
    public string Status { get; set; } 

    [Required] 
    [Display(Name = "First Name")] 
    public string FirstName { get; set; } 

    [Required] 
    [Display(Name = "Last Name")] 
    public string LastName { get; set; } 

    [Display(Name = "Last Modified")] 
    public DateTime LastModificationDate { get; set; } 

    //navigations properties 
    public Affiliation Affiliation { get; set; } 
    public Issue Issue { get; set; } 
    public RequestType RequestType { get; set; } 

    //foreign keys 
    [Display(Name = "Affiliation")] 
    public byte AffiliationId { get; set; } 
    [Display(Name = "Issue")] 
    public int IssueId { get; set; } 
    [Display(Name = "Request Type")] 
    public byte RequestTypeId { get; set; } 


} 

CreateRequestViewModel 클래스 : 내가 모델 클래스를 반영하는 데이터베이스 테이블에있는 필드의 일부를 업데이트 할 경우

public class CreateRequestViewModel 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public string FullName { get; set; } 


    public IEnumerable<Affiliation> Affiliations { get; set; } 
    public IEnumerable<Issue> Issues { get; set; } 

    [Required(ErrorMessage = "Required!")] 
    public byte Affiliation { get; set; } 
    [Required(ErrorMessage = "Required!")] 
    public int Issue { get; set; } 
} 

그러나, 내가 가진 필수 속성을 모두로드 한 다음 "필수"데이터 주석으로 인해 다시 저장하십시오. 문제는 일부 속성을 업데이트해야하지만 모든 속성을 업데이트하지 않아도된다는 것입니다 (예 : FirstName 또는 LastName 값을 변경하지 않음).

내 질문 : 내 Model 클래스에서 "필수"데이터 주석 속성을 제거하고 해당 데이터 주석을 viewModel에서 사용자 입력으로 설정해야합니까? 그런 다음 데이터베이스 테이블의 필드에 대해 "NOT NULL"제약 조건을 잃지 만 modelView를 통해 적용됩니다. 또는 전체 Model 개체를로드하고 dbcontext에서 .SaveChanges()를 호출하기 전에 모든 속성을 다시 저장해야합니까?

참고 : 내 모델 및 viewModel에서 몇 가지 추가 속성을 제거하여 여기에서 코드를 줄입니다.

편집; 모델 변경을 피하기 위해 다음 코드를 구현했습니다. 잘 작동하는 것 같습니다.

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Details(DetailsViewModel request) 
    { 

     var model = new Request 
     { 
      Id = request.Id, 
      RequestDate = request.RequestDate, 
      Status = request.Status, 
      FirstName = request.FirstName, 
      LastName = request.LastName, 
      LastModificationDate = DateTime.Now, 
      AffiliationId = request.AffiliationId, 
      IssueId = request.IssueId, 
      RequestTypeId = request.RequestTypeId, 

     }; 

     _context.Requests.Attach(model); 
     var entry = _context.Entry(model); 
     entry.Property(e => e.Status).IsModified = true; 
     entry.Property(e => e.AffiliationId).IsModified = true; 
     entry.Property(e => e.IssueId).IsModified = true; 
     entry.Property(e => e.RequestTypeId).IsModified = true; 
     entry.Property(e => e.LastModificationDate).IsModified = true; 

     _context.SaveChanges(); 

     return RedirectToAction("Requests"); 

답변

1
  1. 만약 이름 다음 당신은 당신의 모델 (표에 해당 필드가 NOT NULL로 표시됩니다 있도록)뿐만 아니라 뷰 모델을 장식한다, 필수 필드가 (그리고 다른 속성 모델에서 필요로 표시) (ModelState 유효성 검사 및 jQuery 유효성 검사기를 사용하는 경우 UI에 오류 메시지 표시)

  2. 업데이트하는 동안 몇 가지 속성 만 업데이트하려면 전체 엔터티를로드하지 않아도됩니다. 특정 속성을 수정 됨으로 정의합니다.

    var entry = context.Entry (귀하의 엔티티); entry.Property (e => e.YourChangedProperty1) .IsModified = true; entry.Property (e => e.YourChangedProperty2).IsModified = true; context.SaveChanges();

+0

그래서 결국이 작업이 끝났습니다.보기에 의해 전달 된 모든 속성을 가져 오는 중이므로 제대로 작동하는지는 확실하지 않습니다. _context.Requests.Attach (model); var entry = _context.Entry (model); entry.Property (e => e.Status) .IsModified = true; entry.Property (e => e.AffiliationId) .IsModified = true; entry.Property (e => e.IssueId) .IsModified = true; entry.Property (e => e.RequestTypeId) .IsModified = true; entry.Property (e => e.LastModificationDate) .IsModified = true; _context.SaveChanges(); –

+0

@Joe Cuevas : 요청 엔터티가 크고 일부 속성 만 업데이트해야하는 경우 * 어떻게 처리 할 수 ​​있습니까? 그러나 그것은 개인적인 선택 일 수도 있습니다. 내가 의심 스러울 때, 나는 프로파일 러/intellitrace에서 생성 된 쿼리를 확인하여 EF가 생성 한 쿼리가 우리가 생각한 것과 가깝게 있는지 확인합니다. – Developer

1

귀하의 데이터 모델에서 의미가있는 곳에 입력하십시오. 데이터 엔티티에 항상 firstname이 필요한 경우이를 입력하십시오.

viewmodel에는 이름이 필요하지 않으면 입력하지 마십시오. 속성을 포함하기 위해 사용자 입력이 필요한 경우 VM의 해당 속성에 required를 넣습니다.

업데이트하기 위해 엔티티를로드하는 것이 좋습니다. 일부 데이터 엔티티를 "수정"하기 위해 VM을 변경하는 것은 아닙니다.

관련 문제