视图模型和基架迁移
本文关键字:迁移 模型 视图 | 更新日期: 2023-09-27 18:33:25
我正在尝试为我的下拉菜单创建一个多个选项选择。我能够让列表框正常工作,但是,我正在尝试存储所选项目,所以我尝试使用 viewmodel 将其存储为集合,但是,我的 .cshtml
文件已经调用了数据库模型,所以我无法将视图模型包含在.cshtml
文件中,因为一个视图只能有一个模型......即使我尝试使用其他方式在.cshtml
中调用视图模型,它也一直说集合是空异常错误......
因此,按照这个精彩的 youtube 视频教程,我决定将ICollection
带到我现有的模型中,如下所示:
public virtual ICollection<Country> Countries{ get; set; }
一切都很顺利,直到它说,我应该进行数据库迁移,因为模型已经改变。
出于安全原因,我需要向 sysadmin 发送任何更新查询以对数据库运行任何表更改,所以我的问题是,当我使用
public virtual ICollection<Country> Countries{ get; set; }
现有表中有哪些变化?我在改变什么?如果没有任何变化,那么我为什么需要进行数据库迁移才能使其生效?每次我在包管理器控制台中运行 update-database 时,我都会收到一个错误,说我没有权限(我熟悉的错误,它要求我将表更改发送到系统管理员(
任何想法将我的收藏存储在视图模型或模型中。模型中显示的 youtube 示例?
当您添加如下属性时:
public virtual ICollection<Country> Countries{ get; set; }
然后,需要在表上添加一个外键,以支持Country
指向具有此属性的模型。
我不确定您在使用视图模型时遇到了什么问题,但它非常简单。只需将需要从模型编辑的任何属性添加到视图模型,然后将视图模型设置为视图的模型。
如果收到错误,指出集合为 null,则需要初始化集合。同样,这些都是非常基本的东西。您可以在视图模型的构造函数中执行此操作,也可以在操作中手动执行此操作,等等。任何对您的应用程序最有意义的东西。
然后,对于选择列表,您必须记住,将发布的值将是标量类型:字符串、int 等。您不能直接发布到需要类似 Country
类的内容,因为模型绑定器不知道如何根据发布的值实例化Country
。通常,您要做的是使用 Id
作为选项的值,然后在后期操作中使用 id 值从数据库中查找实际对象,然后最终将这些对象附加到模型中。
查看模型
public class FooViewModel
{
public FooViewModel()
{
SelectedCountryIds = new List<int>();
}
...
public List<int> SelectedCountryIds { get; set; }
public IEnumerable<SelectListItem> CountryChoices { get; set; }
}
控制器
private void PopulateCountryChoices(FooViewModel model)
{
model.CountryChoices = db.Countries.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.Name
});
}
public ActionResult Foo()
{
var model = new FooViewModel();
PopulateCountryChoices(model);
return View(model);
}
[HttpPost]
public ActionResult Foo(FooViewModel model)
{
if (ModelState.IsValid)
{
var foo = new Foo
{
// map properties from view model
Countries = db.Countries.Where(m => model.SelectedCountryIds.Contains(m.Id))
}
db.Foos.Add(foo);
db.SaveChanges();
return RedirecToAction("Index");
}
// Posted form has errors
PopulateCountryChoices(model);
return View(model);
}
视图
@model Namespace.To.FooViewModel
...
@Html.ListBoxFor(m => m.SelectedCountryIds, Model.CountryChoices)