gpt4 book ai didi

entity-framework - MVC 5 通过重用 EF 生成的代码使用 ViewModel 进行编辑

转载 作者:行者123 更新时间:2023-12-02 07:28:55 24 4
gpt4 key购买 nike

我有一个业务模型和一个EditBusinessViewModel

在 MVC 4 中,我会使用类似这样的代码来编辑记录:

[HttpPost]
public ActionResult Edit(MainMenu mainmenu)
{
if (ModelState.IsValid)
{
db.MainMenus.Attach(mainmenu);
db.ObjectStateManager.ChangeObjectState(mainmenu, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(mainmenu);
}

现在 MVC 5 中自动生成的代码如下所示,我已将此操作修改为仅包含我的 EditBusinessViewModel 中的字段并将其命名为 Edit2:

[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Edit2([Bind(Include = "ID,BusinessName,BusinessDescription,BusinessAddress,BusinessPhoneOne,BusinessPhoneTwo,BusinessWeb,BusinessEmail,BusinessMelRef")] EditBusinessViewModel business)
{
if (ModelState.IsValid)
{
db.Entry(business).State = EntityState.Modified;
db.SaveChanges();
return Redirect("~/Home/Index/" + business.ID);
}
return View(business);
}

我有 Get 部分工作,我的 ModelView 通过返回工作:

return View(new EditBusinessViewModel(business));

但是当我回发时,这一行出现错误:

db.Entry(business).State = EntityState.Modified;

实体类型 EditBusinessViewModel 不是当前上下文模型的一部分。它不是哪个,我猜是 ViewModel 的原因?

我想知道的是我可以使用此代码还是我应该做的其他事情?

更新

我一直在深入思考这个问题,而 ViewModel 就是一个 ViewModel 所以现在我有:

[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Edit2([Bind(Include = "ID,BusinessDescription,BusinessAddress,BusinessPhoneOne,BusinessPhoneTwo,BusinessWeb,BusinessEmail,BusinessMelRef")] EditBusinessViewModel business)
{
if (ModelState.IsValid)
{
business.UserEmail = User.Identity.GetUserName();

Business newbus = db.Businesses.Find(business.ID);
{
newbus.BusinessDescription = business.BusinessDescription;
newbus.BusinessAddress = business.BusinessAddress;
};

db.Entry(newbus).State = EntityState.Modified;
db.SaveChanges();
return Redirect("~/Home/Index/" + business.ID);
}
return View(business);
}

通过这种方式,我从 View 模型中的 View 发回我需要的数据,通过匹配的 ID 在数据库中找到实体,并使用 EF 脚手架代码更新它。

有没有更好的办法?

最佳答案

好吧,由于我相信您在问题本身中指出的原因,您将无法使用当前代码。您正在使用两种不同的类型,一种是从数据库表映射的,另一种是您专门用于 View 但未映射的。你的实体模型,你没有说哪个版本的 EF,但对于 MVC 5,我假设它是 6 或 6.1。

因此,您拥有由 EF 文本模板生成的实体 POCO,并且拥有 ViewModel。即使属性相同,EF 也不会采用您的 ViewModel 类型,因为它在 edmx 中没有映射定义,这就是它说它不在您已经认识到的当前上下文中的原因。

虽然在这个系统中有一些不错的工作方式。如果您希望使用单独的实体和 ViewModel,我个人在我自己的大部分代码中都会这样做。你可以:

  1. 您似乎有一个 ID,如果该 ID 指向 EF 模型上的唯一 ID,您可以查找具有该 ID 的实体,然后使用 ViewModel 中的值更新该实体的值然后使用 StateModified 而不是 ViewModel 保存实体。
  2. 如果模型和 ViewModel 之间的属性完全相同或非常相似,您可以查看类似 AutoMapper 的东西,https://github.com/AutoMapper/AutoMapper ,这将使您能够将 ViewModel 直接映射到实体模型类型的实例。
  3. 如果您的 Model 和 ViewModel 有很大不同,您可以构建一个静态转换,不确定有多少人这样做,但我喜欢他们。本质上,您定义了两个静态方法,使您能够将模型转换为 View 模型,反之亦然。好处是您可以在需要执行此操作的任何地方调用一个方法,如果任一类型的结构发生变化,您只需在一个位置更新它。
  4. 您说在 MVC 5 中自动生成代码,您可能只是指 EF 5 附带的默认示例代码,但我认为您是在谈论 MVC 5 脚手架。 http://www.asp.net/visual-studio/overview/2013/aspnet-scaffolding-overview ;如果是这样,这些代码不需要太多改动,至少在 Controller 端不需要,除非你有专业领域逻辑,它看起来不像你那样。如果你想使用单独的 ViewModel,我想你可以结合上面的建议之一,但脚手架的要点是删除在为基本 CRUD 方法公开数据库模型时必须做的大部分管道。

如果我没有找到您要查找的内容,请在评论中回复。此外,在没有看到您的两个模型的类定义的情况下,很难为上述建议提供代码示例。我认为这些描述应该足够了,如果你认为一个能很好地适合你的用例?但是,如果您想要一些简单的代码示例,请使用这些类的代码更新您的答案,我可以提供一些。

关于entity-framework - MVC 5 通过重用 EF 生成的代码使用 ViewModel 进行编辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24299066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com