2016-07-15 88 views
0

我目前的問題(可能)不一定與MVC 6直接相關,但是如何與數據庫協同工作,因此任何有關此問題的幫助/建議都將不勝感激。從網站更新數據庫項目

對於這個問題的緣故,讓我們說,我們有一個非常簡單數據庫具有以下表(C#類),我們正在使用實體框架與數據庫工作]:

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 
} 

該演示將用於超級簡易購物清單應用,其中在系統中註冊的用戶(ShoppingUser可以具有列表ShoppingItem,其中用戶可以決定物品的文本(例如麪包,黃油,西紅柿等)。 ..)以及數量(3件,5kg,...簡單字符串)

之後,在我的ASP.NET Core應用程序中,我定義了一個與數據庫通信的存儲庫,並且可以訪問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控制器,用於任一GETPOSTDELETE,...,其用於客戶端應用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是不可見的)。

這是它的樣子:

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應用程序的通信,我用簡單的$http.get$http.post呼籲檢索/發佈更新後的數據。

最後一個問題:

我的問題是,如果用戶決定無論是從他的購物清單中刪除的項目,或決定改變或者文本/數量的內容(也就是說,原來在數據庫它是西紅柿 - 5公斤,但他設法購買只有2公斤,因此改變數量爲西紅柿 - 3公斤),應用程序如何明白哪些元素實際上已被改變,以及如何?我在這種情況下遇到的問題是,我們不再公開項目的數據庫ID。

如果我正在寫一個桌面應用程序,在這裏我就不必創建此子視圖(ShoppingItemViewModel),我的EntityFramework具有足夠的智能來檢查我的數據庫&更新所有的變化。不幸的是,在這種情況下,我不明白這是如何實現的。

當我在想這件事我來用下面的:添加一個新的屬性到ShoppingItemShoppingItemViewModelpublic string sCustomKey {get; set; },這將作爲每個項目的唯一關鍵。這樣,我們不再需要暴露我們的數據庫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 Core和Web項目。

回答

0

我覺得你誤解了一些東西。

這裏是棘手的部分(至少對我來說)。從我所瞭解的視頻教程中,我永遠不會(或幾乎不會)將我的真實數據庫模型公開給網站(我想這是出於安全原因)。由於(從我的GET方法可見),我已經宣佈我的ShoppingItemViewModel只包含我想要公開給用戶的屬性(例如,意味着我的項目ID不可見)。

視圖模型< =>域模型< => ReadModel(數據庫模型)

的一點是,你不應該用你的ReadModel(數據庫模型)在表示層視圖模型的(MVC)。所有三個模型都將具有身份。

+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存在/有效的項目。 或者,您可以爲您的物品/產品使用Guid,因爲可以輕鬆預測ID(int)。

  2. 至於更新項目,您不應該使用「用戶名」作爲標識符(購物車),因爲這可以由調用客戶端預測/更改。您可以使用Guid或者堅持(對Db)或者 內存。如果此Guid屬於此用戶名/ emailAddress,您也可以添加驗證。因此,更新購物車中的物品,可以考慮一次添加/刪除一個,如果這是可行 而不是發送物品列表。

相關問題