Asp.net mvc 使用实体框架(MVC3)更新导航属性
我很难弄清楚如何使用实体框架更新导航属性。我使用了数据库优先的方法,并设置了所有适当的FK关系。下面是我正在使用的两个表的外观: 费率配置文件Asp.net mvc 使用实体框架(MVC3)更新导航属性,asp.net-mvc,entity-framework,razor,Asp.net Mvc,Entity Framework,Razor,我很难弄清楚如何使用实体框架更新导航属性。我使用了数据库优先的方法,并设置了所有适当的FK关系。下面是我正在使用的两个表的外观: 费率配置文件 RateProfileID 档案名称 费率 拉蒂德 RateProfileID(FK) 我要更新的其他几个属性 一个费率配置文件可以/将有多个费率。我为RateProfile构建了编辑页面,以显示RateProfile实体及其所有关联的费率实体的编辑器,并将所有这些内容粘贴在带有提交按钮的表单中。我可以很好地显示所有内容,但我的更改只会针对模型类
- RateProfileID
- 档案名称
- 拉蒂德
- RateProfileID(FK)
- 我要更新的其他几个属性
@model PDR.Models.RateProfile
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>RateProfile</legend>
@Html.HiddenFor(model => model.RateProfileID)
@Html.HiddenFor(model => model.LoginID)
<div class="editor-label">
@Html.LabelFor(model => model.ProfileName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ProfileName)
@Html.ValidationMessageFor(model => model.ProfileName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.isDefault)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.isDefault)
@Html.ValidationMessageFor(model => model.isDefault)
</div>
<div>
<fieldset>
<legend>Dime</legend>
<table>
<tr>
<th>
Min
</th>
<th>
Max
</th>
<th>
Price
</th>
<th></th>
</tr>
@foreach (var rate in Model.Rates)
{
<tr>
<td>
@Html.EditorFor(modelItem => rate.minCount)
@Html.ValidationMessageFor(model => rate.minCount)
</td>
<td>
@Html.EditorFor(modelItem => rate.maxCount)
@Html.ValidationMessageFor(model => rate.maxCount)
</td>
<td>
@Html.EditorFor(modelItem => rate.Amount)
@Html.ValidationMessageFor(model => rate.Amount)
</td>
</tr>
}
</table>
</fieldset>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
公共部分课程费率
{
公共int-RateID{get;set;}
公共int-RateProfileID{get;set;}
公共字符串大小{get;set;}
公共十进制数{get;set;}
public int minCount{get;set;}
public int maxCount{get;set;}
公共内部面板ID{get;set;}
公共虚拟面板面板{get;set;}
公共虚拟速率配置文件速率配置文件{get;set;}
}
公共部分类费率概况
{
公共费率简介()
{
this.Rates=newhashset();
}
公共int-RateProfileID{get;set;}
公共字符串ProfileName{get;set;}
public int LoginID{get;set;}
公共布尔值是默认值{get;set;}
公共虚拟登录{get;set;}
公共虚拟ICollection Rates{get;set;}
}
您将foreach
更改为for
语句,并尝试模型绑定是否正常工作
@for (var int i = 0; i < Model.Rates; i++)
{
<tr>
<td>
@Html.EditorFor(modelItem => Model.Rates[i].minCount)
@Html.ValidationMessageFor(model => Model.Rates[i].minCount)
</td>
<td>
@Html.EditorFor(modelItem => Model.Rates[i].maxCount)
@Html.ValidationMessageFor(model => Model.Rates[i].maxCount)
</td>
<td>
@Html.EditorFor(modelItem => Model.Rates[i].Amount)
@Html.ValidationMessageFor(model => Model.Rates[i].Amount)
</td>
</tr>
}
(var int i=0;i@for
{
@EditorFor(modelItem=>Model.Rates[i].minCount)
@Html.ValidationMessageFor(model=>model.Rates[i].minCount)
@EditorFor(modelItem=>Model.Rates[i].maxCount)
@Html.ValidationMessageFor(model=>model.Rates[i].maxCount)
@EditorFor(modelItem=>Model.Rates[i].Amount)
@Html.ValidationMessageFor(model=>model.Rates[i].Amount)
}
那么,当您在Edit foreach语句上设置断点并检查rateprofile.Rates中的内容时会发生什么
请记住,从视图返回的模型不是您分发的原始对象,而是在控制器功能中从头创建的断开连接的对象
还有,为什么费率是哈希集?不要将数据库引用约束与UI约束混为一谈,因为这只会增加混淆:)
马克在这里建议的是正确的。表单上的字段应命名为Rates[0].ProfileName、Rates[1].ProfileName等,但由于您有一个HashSet,我不确定MVC将如何将这些字段重新生成到模型中
使用断点进行测试,然后按照Mark的建议进行操作,我建议您使用数组或列表替换哈希集。视图中的所有内容都已正确显示。它从表中为导航属性提取正确的记录,并将它们显示得很好。当我单击“保存”按钮并转到“HttpPost编辑”操作时,我无法持久化所做的任何更改。我知道问题不在于显示,而在于绑定速率的模型。。问题是,如果不生成html元素属性的“name”,子属性的绑定就不会发生。使用foreach时,生成的ID不适合模型绑定。太好了!我没有意识到foreach循环使用htmlhelper类为所有子循环命名相同的名称。非常感谢你。我一直在寻找这个问题的答案大约3个小时,这是一个非常简单的解决方案@JoshBlade很高兴知道解决方案解决了这个问题,如果你觉得答案是有益的,请帮我一个忙,将它标记为答案。我之前曾尝试过这样做,但这是我的第一篇帖子,我没有足够的声誉来投票。马克的解决方案为我解决了这个问题。模型是从我的edmx自动生成的,edmx是从我的数据库自动生成的。当我在调试模式下检查导航属性时,它们是原始值,但我不知道如何让它将新值传递给编辑操作。不过,整个foreach vs for(inti…)的解决方案似乎非常不直观。
public partial class Rate
{
public int RateID { get; set; }
public int RateProfileID { get; set; }
public string Size { get; set; }
public decimal Amount { get; set; }
public int minCount { get; set; }
public int maxCount { get; set; }
public int PanelID { get; set; }
public virtual Panel Panel { get; set; }
public virtual RateProfile RateProfile { get; set; }
}
public partial class RateProfile
{
public RateProfile()
{
this.Rates = new HashSet<Rate>();
}
public int RateProfileID { get; set; }
public string ProfileName { get; set; }
public int LoginID { get; set; }
public bool isDefault { get; set; }
public virtual Login Login { get; set; }
public virtual ICollection<Rate> Rates { get; set; }
}
@for (var int i = 0; i < Model.Rates; i++)
{
<tr>
<td>
@Html.EditorFor(modelItem => Model.Rates[i].minCount)
@Html.ValidationMessageFor(model => Model.Rates[i].minCount)
</td>
<td>
@Html.EditorFor(modelItem => Model.Rates[i].maxCount)
@Html.ValidationMessageFor(model => Model.Rates[i].maxCount)
</td>
<td>
@Html.EditorFor(modelItem => Model.Rates[i].Amount)
@Html.ValidationMessageFor(model => Model.Rates[i].Amount)
</td>
</tr>
}