我目前的問題(可能)不一定與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控制器,用於任一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是不可見的)。
這是它的樣子:
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具有足夠的智能來檢查我的數據庫&更新所有的變化。不幸的是,在這種情況下,我不明白這是如何實現的。
當我在想這件事我來用下面的:添加一個新的屬性到ShoppingItem
和ShoppingItemViewModel
:public 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項目。
謝謝你的回答。我也從其他教程中瞭解到,我不應該直接在我的表示層中使用我的數據庫模型,但是我認爲這是爲了隱藏模型的某些屬性(如ID等)。如果你說所有三種模型都可以訪問ID(身份),那麼分離它們有什麼意義呢? –
當您在處理小型項目時,很難發現模型之間的差異,隨着項目的發展變得越來越大,您的模型也會隨之演變。詳細答案閱讀此:[鏈接](http://stackoverflow.com/questions/821276/why-should-i-isolate-my-domain-entities-from-my-presentation-layer) – QuietNaN
謝謝你的帖子。所以如果我明白如果正確,我也可以在我的視圖模型中公開我的ID? –