理解如何在ASP.net中处理数据时遇到问题核心
我试图学习ASP.Net Core,而且我很难弄清楚如何在MVC'样式'(?)中移动数据。我所关注的微软网站上的ASP.NET Core教程并不涉及模型之间的任何关系。 (对他们来说,似乎是一个愚蠢的疏忽?)也许我的Google-Fu关闭了,所以如果这是明显的,或者任何人有一些阅读材料,我可以看看ASPNETCore,我会很感激。理解如何在ASP.net中处理数据时遇到问题核心
我有两个模型。一个叫设备,另一个叫做设备类型。 在我的设备模型中,我有一个对DeviceType属性的引用。
public class Device{
[Key]
public int ID {get; set;}
[Required]
[Display(Name = "Device Name")]
public String deviceName {get; set;}
[Required]
[Display(Name="Description")]
public String deviceDescription {get; set;}
[Required]
[Display(Name="Type")]
public DeviceType deviceType{get; set;}
}
public class DeviceType{
[Key]
public int ID {get; set;}
[Required]
[Display(Name="Type")]
public String name {get;set;}
[Required]
[Display(Name="Description")]
public String description {get;set;}
}
我想知道如何为每个动作(CRUD)引用并获取特定Device对象的deviceType。我也不明白如何在处理我的视图时参考相关的设备类型。
GET创建 *如何让我的DeviceTypes的选择列表,以便用户可以创建一个设备,然后选择它是什么类型的设备? *我对View部分做了一些研究,看起来我需要使用速记Razor“@ model.SelectList()”的语法,但这些参数让我感到困惑。我不明白它要求什么。以下是控制器现在的操作。
public IActionResult Create()
{
return View();
}
指数 *在显示所有设备的循环,我将如何还包括在设备的结果表中的设备类型的名字吗? *在视图中,我会假设我可以使用@ Html.LabelFor来显示数据的名称是什么,但是如何获得实际值?
public async Task<IActionResult> Index()
{
return View(await _context.Device.ToListAsync());
}
更新/编辑 *我怎么会检索设备对象设备类型,然后允许用户编辑呢?
// GET: Devices/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var device = await _context.Device.SingleOrDefaultAsync(m => m.ID == id);
if (device == null)
{
return NotFound();
}
return View(device);
}
删除 *我还没有在这看着呢,但我在这里把它在编程的情况下其他动作时,那里有什么注意事项?
// GET: Devices/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var device = await _context.Device
.SingleOrDefaultAsync(m => m.ID == id);
if (device == null)
{
return NotFound();
}
return View(device);
}
同样,如果除了微软的“用Mac和Linux构建一个带有Visual Studio代码的asp.net核心应用程序”外,我还可以看到其他一些资源,这将解释如何在视图/控制器内部的模型中引用关系,这很好。
谢谢
首先,我假设正在这里使用实体框架,因为这是迄今为止最常用的设置。
获取deviceType
随着EF,关系可以懒洋洋地,兴致勃勃,还是明确地加载。延迟加载是自动驾驶仪的方法:当你需要时,数据只是神奇的。但是,为了启用延迟加载,该属性必须为virtual
。这是因为EF必须覆盖该属性以向其添加延迟加载逻辑,并且如果该属性不是虚拟的,则不能这样做。
public virtual DeviceType deviceType{get; set;}
或者,您可以急于或显式加载您的关系。显式加载非常有所有懒惰加载没有专业人士,所以它不是真正的建议,除非你是因为一个特定的原因。不过,你可以做到这一点通过:
context.Entry(device).Reference(m => m.deviceType).Load();
最后,你可以热切加载的关系,但这必须与初始查询(因此,“渴望”)一起完成。
var devices = context.Devices.Include(m => m.deviceType);
没有做其中的一个,你的关系属性将null
。
创建一个下拉列表中的设备类型
在你看来,你会很明显地要使用Html.DropDownListFor
。但是,您有一个问题,因为您没有要绑定的Device
上的媒体资源。 select
的发布值将是一个简单的类型,如整数ID,因此您无法将其直接绑定到像deviceType
这样的属性。你有两个选择:
-
属性添加到
Device
为外键,而不是依赖隐一个EF将创建:public int deviceTypeId { get; set; }
与像上面的属性创建一个视图模型。在发布后,您会将视图模型中的值映射到您的实体上,当涉及到
deviceTypeId
时,您将使用它从数据库中提取适当的设备类型,然后使用该设置在您的实体上设置deviceType
。
接下来,你需要一个IEnumerable . Don't bother creating an actual
SelectList`实例。剃刀可以照顾到这一点,而当你让剃刀处理它时,事情通常会更顺利。创建是相当直接:
ViewBag.DeviceTypeOptions = context.DeviceTypes.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.Name
});
然后,在你的看法:
@Html.DropDownListFor(m => m.deviceTypeId, (IEnumerable<SelectListItem>)ViewBag.DeviceTypeOptions)
如果你使用一个视图模型,而不是直接的实体,这是更好地把选项对查看模型而不是ViewBag
,但您可以通过任何方式完成工作。
获取deviceType
名称
LabelFor
是用于生成实际的HTML label
。假设DeviceType
有一个属性Name
的结果将是:
<label for="Name">Name</label>
内部,LabelFor
将调用DisplayNameFor
,这是你如何获得属性的实际名称(或从Display
属性的值)。那结果将只是:
Name
你要寻找的是DisplayFor
或只是简单的@
语法。以下是功能上等同并且将两个输出类似Some Awesome Device Type
:
@Html.DisplayFor(m => m.Name)
@Model.Name
编辑deviceType
这一个对堆栈溢出有点过于宽泛。简而言之,您只需在窗体中为其呈现字段,就像其他任何内容一样。您只需要注意输入的命名,因为您需要维护对象层次结构。例如,如果您正在编辑一个Device
,你必须输入为deviceType
,如:
<input type="text" name="deviceType.Name" />
但是,只要您使用*For
风格佣工,本身工作了大部分。
删除
有算不上什么特别的考虑这里,作为EF的默认值是级联。如果由于某种原因,你决定(或者已经决定在现有的数据库中),以便不级联,那么在删除设备之前,你只需要删除设备类型即手动做同样的事情级联会。
获得设备列表时,假设这是使用实体框架包括设备类型,使用包括像_context.Device.Include(d => d.DeviceType).ToListAsync()
。这将会......包括您指定的关联实体。实体框架还有很多,所以我建议在处理模型和上下文时查找更多信息。
至于你可以选择的类型列表,你首先需要分别获得可用设备类型的列表,然后将它传递给视图(在viewbag中,或者你选择),然后......我还没有和MVC核心的工作很多,但我怀疑这是相当类似老版本,但无论如何像MVC6 Dropdownlist of Countries
首先你需要包括外键在您的设备型号:
public int DeviceTypeID {get; set;}
然后你应该包括这个设备类型属性如何answered here:
_context.Device.Include(d => d.DeviceType).ToListAsync()
EF Core尚未对延迟加载进行加载。 https://docs.microsoft.com/en-us/ef/core/querying/related-data – Alexan
@Alex:是的,我忘了这一点。或者,也许我只是觉得他们已经排序了将近两年;)。没什么大不了。老实说,我还没有看到很多好的理由来延迟加载,反正。一般来说,你只需要加载你需要的一切。 –
即使EF支持它,也不要在网络应用程序中使用延迟加载,只要您可以提供帮助。这是为什么:http://ardalis.com/avoid-lazy-loading-entities-in-asp-net-applications – ssmith