0

현재 문제는 (아마도) MVC 6과 직접 관련이있는 것은 아니지만 데이터베이스 작업이 실제로 어떻게 작동하는지에 대한 것이므로이 문제에 대한 도움이나 제안은 인정 될 것입니다.웹 사이트의 데이터베이스 항목 업데이트

public class ShoppingUser 
{ 
    public int Id { get; set; } 
    public string UserName { get; set; } 

    public ICollection<ShoppingItem> Items { get; set; } 
} 

public class ShoppingItem 
{ 
    public int Id { get; set; } 
    public string Quantity { get; set; } 
    public string Text { get; set; } 
    public bool ToRemove { get; set; }//if item has been bought, it can be removed from the shopping list 
} 

:

이 질문을 위해서

, 이제 우리는 [데이터베이스로 작업하는 우리는 엔티티 프레임 워크를 사용] 다음 표 (C#을 클래스)와 매우 간단한 데이터베이스가 있다고 가정 해 봅시다 이 데모는 시스템에 등록 된 사용자 (ShoppingUser)가 ShoppingItem의 목록을 가지고 사용자가 항목의 텍스트 (예 : 빵, 버터, 토마토 등)를 결정할 수있는 슈퍼 듀퍼 간단한 쇼핑 목록 앱을위한 것입니다. ..) 그리고 수량 (3 개, 5kg, ... 단순한 문자열)

나중에 내 ASP.NET 코어 응용 프로그램에서 데이터베이스와 통신하는 저장소를 정의했으며 ShoppingItem 클래스에 액세스 할 수 있습니다 (우리는 현재 로그인 한 사용자의 쇼핑 항목에만 관심이 있으므로). 어떤 방법의

예 우리는 여기에 사용할 수 있습니다

public IEnumerable<ShoppingItem> ReturnUserItems(string sUsername) 
    { 
     if (string.IsNullOrWhiteSpace(sUsername)) 
      return null; 

     var result = _context.ShoppingUsers.Include(n => n.Items).Where(n => n.UserName == sUsername).FirstOrDefault(); 

     if (result != null) 
      return result.Items; 
     else 
      return null; 
    } 

마지막으로 우리가 JsonResult과 API 컨트롤러가 하나 GET, POST, DELETE, ..., 클라이언트 측 AngularJS와 응용 프로그램 사이의 통신에 사용되는 및 우리의 서버 측 논리. GET 방법의

예 :

// GET: /<controller>/ 
    [HttpGet("")] 
    public JsonResult Get(string sUserName) 
    { 
     try 
     { 
      var results = _repository.ReturnUserItems(User.Identity.Name); 

      if (results != null) 
      { 
       var result = Mapper.Map<IEnumerable<ShoppingItemViewModel>>(results); 
       return Json(result); 
      } 

      Response.StatusCode = (int)HttpStatusCode.OK; 
     } 
     catch (Exception ex) 
     { 
      Response.StatusCode = (int)HttpStatusCode.BadRequest; 
      return Json(new { Message = ex.Message }); 
     } 

     return null; 
    } 

여기 (적어도 나를 위해) 까다로운 부분 온다. 내가 배운 비디오 튜토리얼에서 웹 사이트에 내 실제 데이터베이스 모델을 노출시키지 않아야합니다 (보안상의 이유로). 그 (위의 내 GET 메서드에서 볼 수 있음)로 인해 내 ShoppingItemViewModel은 사용자에게 표시하려는 속성 만 포함합니다 (예 : 내 항목의 ID가 표시되지 않음을 나타냄). 내가 업데이트 된 데이터를 게시/검색하는 간단한 $http.get$http.post 전화를 사용하고

public class ShoppingItemViewModel 
{ 
    public string Quantity { get; set; } 
    [Required] 
    public string Text { get; set; } 
    [Required] 
    public bool ToRemove { get; set; }//if item has been bought, it can be removed from the shopping list 
} 

그리고 내 AngularJS와 응용 프로그램에서 통신을 위해 :

이것은처럼 보이는 방법이다.

마지막 질문 : 사용자가 자신의 쇼핑 목록에서 항목을 삭제하거나 결정, 또는 하나의 텍스트/수량의 내용을 변경하기로 결정하면

내 문제는, (의미되는 그 원래의 데이터베이스가 토마토 - 5kg 이었지만 그는 2kg 밖에 살 수 없었으므로 수량을 토마토 - 3kg)으로 변경했는데 실제로 변경된 요소와 방법을 앱에서 어떻게 이해할 수 있습니까? 이 경우 문제는 더 이상 항목의 데이터베이스 ID가 노출되지 않는다는 것입니다.

이 하위보기 (ShoppingItemViewModel)를 만들지 않아도되는 데스크톱 응용 프로그램을 작성하는 경우 EntityFramework는 데이터베이스의 모든 변경 사항을 & 업데이트로 검사 할만큼 지능적입니다. 불행히도이 경우, 어떻게 달성 할 수 있는지 이해하지 못합니다.나는 그것에 대해 생각하면

나는 다음과 함께 : 모든 항목에 대한 고유 키 역할을 것이다, public string sCustomKey {get; set; } 다음 ShoppingItemShoppingItemViewModel에 새로운 속성을 추가합니다. 이렇게하면 더 이상 데이터베이스 ID를 노출 할 필요가 없지만 '가짜'ID가 노출됩니다.

두 번째 질문 : 내 솔루션이 정확한지, 데이터베이스의 항목을 업데이트하는 가장 좋은 방법은 무엇입니까? 내가 생각할 수있는 유일한 방법은 데이터베이스의 모든 항목을 반복하고 변경 사항을 수동으로 확인하는 것입니다. 내가 생각하고있는 어떤

예 :

//IEnumerable<ShoppingItem> would be re-mapped result of ShoppingItemViewModel we have received back from the website 
    public void UpdateValues(IEnumerable<ShoppingItem> items, string sUserName) 
    { 
     //retrieves list of shopping items for specified customer 
     var allItems = _context.ShoppingUsers 
      .Include(n => n.Items) 
      .FirstOrDefault(n => n.UserName == sUserName); 

     //updates the values 
     foreach (var sItem in items) 
     { 
      var updatedItem = allItems.Items.FirstOrDefault(n => n.Text == sItem.sCustomKey); 

      if (updatedItem == null) 
      { 
       //create new item 
       var newItem = new ShoppingItem(); 
       newItem.Text = sItem.Text; 
       newItem.ToRemove = sItem.ToRemove; 
       allItems.Items.Add(newItem); 
      } 
      else 
       updatedItem.ToRemove = sItem.ToRemove; 
     } 


     _context.SaveChanges(); 
    } 

그러나이 방법은 나에게 잘 보이지 않는다.

ASP.NET 코어 및 웹 프로젝트를 사용하는 방법을 배우면서 이러한 문제에 대한 도움을 받으실 수 있습니다.

답변

0

나는 당신이 뭔가 오해했다고 생각합니다.

여기에 까다로운 부분이 있습니다 (적어도 나를 위해). 내가 배운 비디오 튜토리얼에서 웹 사이트에 내 실제 데이터베이스 모델을 노출시키지 않아야합니다 (보안상의 이유로). 위의 내 GET 메소드에서 볼 수있는 것처럼 사용자에게 표시하려는 속성 만 포함하는 ShoppingItemViewModel을 선언했습니다 (예 : 내 항목의 ID가 표시되지 않음).

뷰 모델 < => 도메인 모델 < => ReadModel (데이터베이스 모델)

점은 프리젠 테이션 계층에서의 ViewModel (MVC)로 ReadModel (데이터베이스 모델)을 사용하지해야한다는 것입니다. 세 모델 모두 신원을가집니다.

+0

답장을 보내 주셔서 감사합니다. 필자는 다른 튜토리얼을 통해 필자의 프리젠 테이션 레이어에서 직접 데이터베이스 모델을 사용해서는 안되지만 모델의 특정 속성 (예 : ID 등)을 숨기는 것으로 생각했습니다. 세 모델 모두 ID (신원)에 액세스 할 수 있다고 말하면, 그 모델을 구분하는 것은 무엇입니까? –

+0

소규모 프로젝트로 작업 할 때 프로젝트가 발전하고 모델이 커짐에 따라 모델 간의 차이점을 감지하기가 어렵습니다. 자세한 답변을 읽어보십시오 : [링크] (http://stackoverflow.com/questions/821276/why-should-i-isolate-my-domain-entities-from-my-presentation-layer) – QuietNaN

+0

게시물 주셔서 감사합니다 . 그래서 올바르게 이해한다면 내 ID 모델을 내 뷰 모델에 노출시킬 수 있습니까? –

1
  1. 첫 번째 질문에서 ViewModels에 항목 ID를 표시하는 것이 좋습니다. 도메인 계층에서 해당 ID가 존재하는 유효성 검사 논리를 추가하거나 유효한 항목을 추가 할 수 있습니다. ID (int)를 쉽게 예측할 수 있으므로 항목/제품에 Guid를 사용할 수 있습니다.

  2. 항목을 업데이트하는 경우 전화 클라이언트가 예측/변경할 수 있으므로 식별자 (장바구니)로는 "사용자 이름"을 사용하지 않아야합니다. Guid를 지속 (Db로)하거나 메모리 내에서 사용할 수 있습니다. 이 Guid가이 username/emailAddress에 속하면 유효성 검사를 추가 할 수 있습니다. 따라서 장바구니의 항목을 업데이트하는 경우 항목 목록을 보내는 대신 이 가능하면 한 번에 하나씩 추가/제거하는 것이 좋습니다.

관련 문제