如何在ASP.NET MVC 3更新复杂的模型 [英] How to update complex model in ASP.NET MVC 3

查看:156
本文介绍了如何在ASP.NET MVC 3更新复杂的模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图更新在单个视图一个复杂的模型。
我使用ASP.NET MVC3,实体框架与code首先,工作单位,通用存储库模式..
但是当我尝试更新的模式,我想出了这个错误:

I am trying to update a complex model in a single view. I am using ASP.NET MVC3, Entity Framework with Code first, unit of work, generic repository pattern.. but when I try to update the model, i come up with this error:

参照完整性约束冲突发生:定义引用约束的属性值是不是本金和依赖对象的关系之间是一致的

下面是我的简化视图模型:

Here is my simplified view model:

public class TransactionViewModel
{
     public Transaction Transaction { get; set; }
     public bool IsUserSubmitting { get; set; }
     public IEnumerable<SelectListItem> ContractTypes { get; set; }
}

下面是我的简化复杂的模型,并且作为例子它的导航属性之一。
事务具有其所有导航属性的一对一关系:

Here is my simplified complex model, and as an example one of its navigation property. Transaction has one to one relationship with all of its navigation properties:

public class Transaction
{
    [Key]
    public int Id { get; set; }

    public int CurrentStageId { get; set; }

    public int? BidId { get; set; }

    public int? EvaluationId { get; set; }

    public virtual Stage CurrentStage { get; set; }

    public virtual Bid Bid { get; set; }

    public virtual Evaluation Evaluation { get; set; }

}

public class Bid
{
    [Key]
    public int Id { get; set; }

    public string Type { get; set; }

    public DateTime? PublicationDate { get; set; }

    public DateTime? BidOpeningDate { get; set; }

    public DateTime? ServiceDate { get; set; }

    public string ContractBuyerComments { get; set; }

    public string BidNumber { get; set; }

    public DateTime? ReminderDate { get; set; }

    public DateTime? SubmitDate { get; set; }

}

使用相同的视图模型,我可以创建一个交易对象,这将填充数据库这样的。

Using the same view model, I am able to create a transaction object, which would populate the database like this.

ID:1,CurrentStageId:1,BidId:1,EvaluationId:1

Id: 1, CurrentStageId: 1, BidId: 1, EvaluationId: 1

但是,当我尝试这些导航属性内更新性能,该行导致错误,在控制器:

but, when I try to update properties within these navigation properties, this line causes the error, in controller:

[HttpPost]
public ActionResult Edit(TransactionViewModel model)
{
    if (ModelState.IsValid)
    {
        -> unitOfWork.TransactionRepository.Update(model.Transaction);
           unitOfWork.Save();
           return RedirectToAction("List");
    }
}

在通用存储库:

public virtual void Update(TEntity entityToUpdate)
{
 -> dbSet.Attach(entityToUpdate);
    context.Entry(entityToUpdate).State = EntityState.Modified;
}

这个问题进一步复杂化,因为我应该能够在单个视图中编辑任何范围内的任何交易对象中的导航属性的字段(属性)的。

推荐答案

我相信例外含义如下:

定义引用约束的属性值... (这是主键属性(= 编号)的值出价键和外键属性(= BidId 交易价值

The property values that define the referential constraints ... (these are the primary key property (= Id) value of Bid and the foreign key property (= BidId) value of Transaction)

...并不一致...... (=有不同的值)

...委托人之间... (= 出价

...和...依赖(= 交易

...关系中的对象。

因此​​,它看起来像下面这样:当MVC模型绑定创建 TransactionViewModel 作为参数的修改行动 model.Transaction.BidId model.Transaction.Bid.Id 是不同的,例如:

So, it looks like the following: When the MVC model binder creates the TransactionViewModel as parameter for the Edit action, model.Transaction.BidId and model.Transaction.Bid.Id are different, for example:


  • model.Transaction.BidId.HasValue 真正,但 model.Transaction.Bid

  • model.Transaction.BidId.HasValue ,但 model.Transaction.Bid 不是

  • model.Transaction.BidId.Value != model.Transaction.Bid.Id

  • model.Transaction.BidId.HasValue is true but model.Transaction.Bid is null
  • model.Transaction.BidId.HasValue is false but model.Transaction.Bid is not null
  • model.Transaction.BidId.Value != model.Transaction.Bid.Id

(第一点是可能的的一个问题。我的猜测是,你有情况2)。

(The first point is probably not a problem. My guess is that you have situation 2.)

这同样适用于 CurrentStage 评估

可能的解决方案:


  • 设置这些属性相同的值你叫你的资料库中的更新方法之前(=黑客)

  • 绑定 TransactionViewModel.Transaction.BidId TransactionViewModel.Transaction.Bid.Id 来两个隐藏形式与领域相同的值,使模型粘合剂填补这两个属性。

  • 使用也是一个视图模型为你的内在交易属性(以及内部的导航属性交易以及)这是为您量身定制视图,您可以适当地映射到控制器操作的实体。

  • Set those properties to the same values before you call the Update method of your repository (=hack)
  • Bind TransactionViewModel.Transaction.BidId and TransactionViewModel.Transaction.Bid.Id to two hidden form fields with the same value so that the model binder fills both properties.
  • Use also a ViewModel for your inner Transaction property (and for the navigation properties inside of Transaction as well) which is tailored to your view and which you can map appropriately to the entities in your controller action.

最后要提的是,这条线......

One last point to mention is that this line ...

context.Entry(entityToUpdate).State = EntityState.Modified;

...没有标志的相关对象( Transaction.Bid )的修改,所以它不会保存 Transaction.Bid任何变化。你必须对相关对象的状态设置为修改以及

... does not flag the related objects (Transaction.Bid) as modified, so it would not save any changes of Transaction.Bid. You must set the state for the related objects to Modified as well.

附注:如果你没有用流利的​​API,任何额外的映射EF所有的关系不是一比一,但一到多,因为你有单独的FK属性。与EF一到一对一的关系需要共享的主键。

Side note: If you don't have any additional mapping with Fluent API for EF all your relationships are not one-to-one but one-to-many because you have separate FK properties. One-to-One relationships with EF require shared primary keys.

这篇关于如何在ASP.NET MVC 3更新复杂的模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆