asp.net-mvc – 如何在ASP.NET MVC 3中更新复杂模型

前端之家收集整理的这篇文章主要介绍了asp.net-mvc – 如何在ASP.NET MVC 3中更新复杂模型前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在单个视图中更新复杂模型.
我正在使用ASP.NET MVC3,Entity Framework with Code first,工作单元,通用存储库模式..
但是当我尝试更新模型时,我想出了这个错误

发生了引用完整性约束违规:定义引用约束的属性值在关系中的主体和从属对象之间不一致.

这是我的简化视图模型:

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

这是我的简化复杂模型,并作为其导航属性之一的示例.
Transaction与其所有导航属性具有一对一的关系:

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; }

}

使用相同的视图模型,我能够创建一个事务对象,它将像这样填充数据库.

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

但是,当我尝试更新这些导航属性中的属性时,此行会在控制器中导致错误

[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;
}

问题更加复杂,因为我应该能够在单个视图中编辑Transaction对象中任何导航属性中的任何字段(属性).

解决方法

我相信例外意味着以下内容

定义引用约束的属性值…(这些是Bid的主键属性(= Id)值和Transaction的外键属性(= BidId)值)

……不一致……(=有不同的值)

……校长之间…(=投标)

……和依赖…(=交易)

……关系中的对象.

因此,它看起来如下所示:当MVC模型绑定器创建Transactionviewmodel作为Edit操作的参数时,model.Transaction.BidId和model.Transaction.Bid.Id是不同的,例如:

> model.Transaction.BidId.HasValue为true但model.Transaction.Bid为null
> model.Transaction.BidId.HasValue为false但model.Transaction.Bid不为null
> model.Transaction.BidId.Value!= model.Transaction.Bid.Id

(第一点可能不是问题.我的猜测是你有情况2.)

这同样适用于CurrentStage和Evaluation.

可能的解决方案:

>在调用存储库的Update方法之前,将这些属性设置为相同的值(= hack)
>将Transactionviewmodel.Transaction.BidId和Transactionviewmodel.Transaction.Bid.Id绑定到具有相同值的两个隐藏表单字段,以便模型绑定器填充这两个属性.
>还可以使用viewmodel作为内部Transaction属性(以及Transaction内部的导航属性),该属性是根据您的视图定制的,您可以将其适当地映射到控制器操作中的实体.

最后一点要提到的是这条线……

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

…不会将相关对象(Transaction.Bid)标记为已修改,因此不会保存Transaction.Bid的任何更改.您还必须将相关对象的状态设置为“已修改”.

附注:如果您没有使用Fluent API for EF的任何其他映射,那么您的所有关系不是一对一的,而是一对多的,因为您有单独的FK属性.与EF的一对一关系需要共享主键.

猜你在找的asp.Net相关文章