我正在练习MVC 5,在我的应用程序中,我有一个控制器方法,应该更新给定用户配置文件的地址信息。
我通过使用上下文对象访问数据库来实现这一点,我首先想到的是将数据库行复制到对象,进行更改,然后使用AddOrUpdate()
方法将其重新放回。但是,我只看到Add()
方法。
所以我做了以下事情:
public ActionResult EditBillingDetails(EditBillingDetailsViewModel model)
{
if (ModelState.IsValid)
{
string id = User.Identity.GetUserId();
ApplicationDbContext db = new ApplicationDbContext();
db.Users.Single(u => u.Id == id).FirstName = model.FirstName;
db.Users.Single(u => u.Id == id).LastName = model.LastName;
db.Users.Single(u => u.Id == id).Email = model.Email;
db.Users.Single(u => u.Id == id).Address = model.Address;
db.Users.Single(u => u.Id == id).City = model.City;
db.Users.Single(u => u.Id == id).ZIP = model.ZIP;
db.Users.Single(u => u.Id == id).Country = model.Country;
db.SaveChanges();
return RedirectToAction("Manage", new { Message = ManageMessageId.ChangeBillingSuccess });
}
return View(model);
}
哪个工作得很好,但是为了逐个查找相同的条目7次只是为了逐个更新每个字段感觉不对。难道没有更好的方法吗?
答案 0 :(得分:4)
如果您从数据库中检索实体,db.SaveChanges()
将负责使用新值更新实体。 EF"追踪"您从数据库查询的实体(在此实例中,对.Single()
的调用)并且知道如果您更改该实体的任何属性,则将更改保留回数据库。如果要创建一个全新的实体,则只需要Add
到数据库。
var user = db.Users.Single(u => u.Id == id);
user.FirstName = model.FirstName;
user.LastName = model.LastName;
user.Email = model.Email;
user.Address = model.Address;
user.City = model.City;
user.ZIP = model.ZIP;
user.Country = model.Country;
db.SaveChanges();
答案 1 :(得分:1)
假设这是Entity-Framekwork并且您还没有更改任何默认配置(缓存),您的代码虽然非常具体,但只有第一个Single()
会调用数据库来检索对象。所以在功能上它将与:
var user = db.Users.Single(u => u.Id == id);
user.FirstName = model.FirstName;
user.LastName = model.LastName;
user.Email = model.Email;
user.Address = model.Address;
user.City = model.City;
user.ZIP = model.ZIP;
user.Country = model.Country;
db.SaveChanges();
可能还有一个额外的(如此微小的)代码执行,具体取决于编译器是否会将IL中的代码更改为我编写的代码。
答案 2 :(得分:1)
为什么不从上下文中获取用户?
public User GetUser(int id)
{
DbContext context = new YourDbContext();
return context.Users.Find(id);
}
public void SaveUser(User user)
{
DbContext context = new YourDbContext();
context.Entry(user).State = EntityState.Modified;
context.SaveChanges();
return;
}
在您的控制器中,您将更新用户的属性并保存:
DbContext context = new YourDbContext();
User user = GetUser(User.Identity.GetUserId());
user.Value1 = model.Value1;
user.Value2 = model.Value2;
SaveUser(user);
return RedirectToAction(...);
答案 3 :(得分:0)
试试这个:
public ActionResult EditBillingDetails(EditBillingDetailsViewModel model)
{
if (ModelState.IsValid)
{
string id = User.Identity.GetUserId();
ApplicationDbContext db = new ApplicationDbContext();
Users usr = db.Users.SingleOrDefault(u => u.Id == id);
if(usr != null)
{
usr.FirstName = model.FirstName;
usr.LastName = model.LastName;
usr.Email = model.Email;
usr.Address = model.Address;
usr.City = model.City;
usr.ZIP = model.ZIP;
usr.Country = model.Country;
db.SaveChanges();
return RedirectToAction("Manage", new { Message = ManageMessageId.ChangeBillingSuccess });
}
return RedirectToAction("Manage", new { Message = "Error" });
}
return View(model);
}
逻辑是只从数据库获取一次详细信息并更新它的所有字段。
请以此为出发点,而不是复制粘贴解决方案。