首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ASP.NET MVC 3 EF CodeFirst - DBContext项编辑

ASP.NET MVC 3 EF CodeFirst - DBContext项编辑
EN

Stack Overflow用户
提问于 2011-08-13 11:53:33
回答 1查看 4.6K关注 0票数 8

我对此感到沮丧,因为我喜欢day...please的帮助。

我有一个发票部分,可以通过使用JQuery追加/移除DOM元素来动态添加新项.我已经知道了如何正确地命名这些元素,这样就可以将它们正确地映射到模型并发送到action参数。

因此,假设我在我的控制器中有一个名为Edit的操作,并带有类型发票的param

代码语言:javascript
复制
[HttpPost]
public virtual ActionResult Edit(Invoice invoice) {
    if (ModelState.IsValid) {
         //code discussed below
    }
    return RedirectToAction("Index");
}

发票参数包含我想要的所有数据。我对此没意见。以下是对象模型。

代码语言:javascript
复制
public class Invoice
{
    [Key]
    public int ID { get; set; }
    public InvoiceType InvoiceType { get; set; }
    public string Description { get; set; }
    public int Amount { get; set; }
    public virtual ICollection<InvoiceItem> InvoiceItems { get; set; }
}

注意InvoiceItems集合-它包含动态插入的发票项的集合。以下是InvoiceItem模型

代码语言:javascript
复制
[Table("InvoiceItems")]
public class InvoiceItem
{
    [Key]
    public int ID { get; set; }

    [ForeignKey("Invoice")]
    public int InvoiceID { get; set; }
    public Invoice Invoice { get; set; }

    public string Description { get; set; }
    public int Amount { get; set; }
}

这就是我被困的地方。

我无法将发票集合InvoiceItems中的项目插入/更新到数据库中。我在谷歌上搜索了很多,我找到了这些解决方案--不幸的是,所有这些都不起作用。

解决方案#1 -一些带有SetValues的奇怪代码:

代码语言:javascript
复制
Invoice origInvoice = db.Invoices.Single(x => x.ID == invoice.ID);
var entry = db.Entry(origInvoice);
entry.OriginalValues.SetValues(invoice);
entry.CurrentValues.SetValues(invoice);
db.SaveChanges();

解决方案#2 -向我的DbContext添加一个新的更新方法:

代码语言:javascript
复制
public void Update<T>(T entity) where T : class
{
   this.Set<T>().Attach(entity);
   base.ObjectContext.ObjectStateManager.ChangeObjectState(entity,System.Data.EntityState.Modified);
 }

解决方案#3 -根据http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx将现有但已修改的实体附加到上下文中

代码语言:javascript
复制
db.Entry(invoice).State = EntityState.Modified;
db.SaveChanges();

解决方案#1的工作方式:更新除新添加的InvoiceItems以外的所有属性。SetValues()忽略ICollection属性。如果我在db.SaveChanges()之前添加了这一行,这就可以了;

代码语言:javascript
复制
origEntry.Entity.InvoiceItems = invoice.InvoiceItems;

...but我认为这根本不是正确的方法。

如何使用解决方案2:根本不工作,因为DbContext类中没有ObjectContext属性。

解决方案#3的工作原理:这个解决方案将更新发票,但否则会忽略InvoiceItems。

附加信息:下面是javascript的一部分,用于生成映射到InvoiceItem属性的item元素。

代码语言:javascript
复制
    window.InvoiceItemIndex++;

    var str = $.tmpl("itemRowTmpl", {
        itemIndexes: '<input type="hidden" name="Invoice.InvoiceItems.Index" value="' + window.InvoiceItemIndex + '"/> \
                      <input type="hidden" name="Invoice.InvoiceItems[' + window.InvoiceItemIndex + '].ID" value="0"/>\
                      <input type="hidden" name="Invoice.InvoiceItems[' + window.InvoiceItemIndex + '].InvoiceID" value="@Model.Invoice.ID"/>',
        itemDescription: '<textarea cols="150" name="Invoice.InvoiceItems[' + window.InvoiceItemIndex + '].Description" rows="2"></textarea>',
        itemAmount: '<input type="text" class="InvoiceItemAmount" style="text-align:right;" name="Invoice.InvoiceItems[' + window.InvoiceItemIndex + '].Amount" />',
    });

最后一个问题:我做错了什么?在数据库中自动插入与另一个模型相关的新的项目集合有什么问题?当父模型成功地更新时,为什么要忽略它呢?

编辑1:更正

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-13 19:24:30

DbEntityEntry.CurrentValues.SetValues只更新标量和复杂属性。它不关心导航属性。这就是为什么您的InvoiceItems集合中的更改没有写入数据库的原因。同样的问题是将Invoice的状态设置为Modified。这只是将标量和复杂属性标记为已修改的属性,而不是任何导航属性。

不幸的是,EF并没有为您提供一个简单的方法来分析导航集合中的哪些项已经添加、删除或仅与数据库中的原始状态相比较,如果更改是在实体与上下文分离时完成的(在示例中的网页上)。

这意味着您必须在数据库中的原始状态与新更改的状态之间进行比较。

代码示例如何这样做--例如:The relationship could not be changed because one or more of the foreign-key properties is non-nullable --示例非常适合您的情况,只需将ParentItem替换为Invoice,将ChildItems替换为InvoiceItems即可。

您还可以从几天前开始查看这个问题,了解其他信息:WCF, Entity Framework 4.1 and Entity's State实际上还有许多其他问题涉及到相同的问题,因为缺少对更新分离对象图的支持(这是一个非常常见的场景)是实体框架的一个更令人不快的限制。

(注意:在MVC控制器中有UpdateModel方法。我不确定此方法是否能够更新完整的对象图(添加、删除和更改集合中的项)。就我个人而言,我不使用它,如果我要使用它,那么就不会使用DB模型,只用于ViewModel更新。)

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7050235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档