【发布时间】:2019-09-13 13:02:03
【问题描述】:
假设我们有 User 实体:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string StatusMessage{ get; set; }
public string PasswordHash { get; set; }
public Group Group { get; set; }
public Referal Referal { get; set; }
}
User-to-Group 具有多对多关系,User-to-Referal有一对多的关系。他们都对 User 有外键约束。
我作为用户突然意识到我目前的状态并不能完全代表我的个性 - 所以我决定改变它。 我们有简单的表格来提交新的状态。
@model User
<form asp-antiforgery="true" method="post" role="form">
<div class="validation" asp-validation-summary="ModelOnly"></div>
<div class="form-group">
<div>
<input hidden asp-for="Id" type="number" name="Id" value="@Model.Id">
</div>
</div>
<div class="form-group">
<label for="Status">Status:</label>
<div>
<input required asp-for="Status" type="text" name="Status">
</div>
</div>
</form>
还有两个动作来处理它。
[HttpGet("account/edit")]
public IActionResult Edit(int accountId, string Status)
{
User user = db.Users.SingleOrDefault(p => p.Id == accountId);
return View(user);
}
[HttpPost("account/edit")]
public IActionResult Edit(int Id, string Status)
{
User user = db.Users.SingleOrDefault(p => p.Id == accountId);
user.StatusMessage = Status;
db.SaveChanges()
return RedirectToAction("MainView");
}
没有看到什么奇怪的东西吗?在 post 方法中,我们再次连接到我们的数据库以获取正确的实体,因此它所拥有的任何关系都将被保存。如果我们只有几个字段要更新,这是一个好方法。但是如果我们有 10-15 个或更多字段,它会变得越来越难看。
[HttpPost("account/edit")]
public IActionResult Edit(int Id, string Status, string FavouriteGirl, string LastWatchedTVShow, int NumberOfFingers, DateTime YearOfFirstKiss, string DogName)
{
User user = db.Users.SingleOrDefault(p => p.Id == accountId);
user.StatusMessage = Status;
user.FavouriteGirl = FavouriteGirl;
user.LastWatchedTVShow = LastWatchedTVShow;
user.NumberOfFingers= NumberOfFingers;
user.YearOfFirstKiss= YearOfFirstKiss;
user.DogName = DogName;
db.SaveChanges()
return RedirectToAction("MainView");
}
在某种程度上很方便,我们明确说明哪些字段将被更改,但它们变成了硬编码,我们可以关注视图中的更改。
处理它的一个好方法是传递 User 对象。
[HttpPost("account/edit")]
public IActionResult Edit(User user)
但实际上我找不到任何将它绑定到实体的好方法。
[HttpPost("account/edit")]
public IActionResult Edit(User user)
{
//None of this will work
User userFromDb = db.Users.SingleOrDefault(p => p.Id == user.Id);
userFromDb = user;
db.SaveChanges();
//we just changed reference to variable, no effect on entity
user.Group = userFromDb.Group;
user.Referal = userFromDb.Referal;
db.SaveChanges();
//will cause FK constraint errors
}
最后,我们将手动更新字段,但来自 userFromDb.StatusMessage = user.StatusMessage 类
所以我想知道是否有比手动更新字段更好的方法来更新实体?
【问题讨论】:
标签: c# entity-framework asp.net-core