加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

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

发布时间:2020-12-16 00:18:33 所属栏目:asp.Net 来源:网络整理
导读:我试图在单个视图中更新复杂模型. 我正在使用ASP.NET MVC3,Entity Framework with Code first,工作单元,通用存储库模式.. 但是当我尝试更新模型时,我想出了这个错误: 发生了引用完整性约束违规:定义引用约束的属性值在关系中的主体和从属对象之间不一致.
我试图在单个视图中更新复杂模型.
我正在使用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的一对一关系需要共享主键.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读