繁体   English   中英

实体框架更新实体

[英]Entity Framework Update Entity

我正在尝试更新实体及其所有关系,但不确定是否可行。 如果不可能的话,最好的方法是什么?

我的ASP MVC控制器...

public ActionResult TimeSheetEdit(Timesheet timesheet, string submitType)
{
    _timesheetRepository.Update(timesheet);
    _timesheetRepository.Commit();

    return RedirectToAction("TimeSheetEdit", new {id=timesheet.TimeSheetId});
}

我的时间表模型具有多个属性,一个属性是另一实体(具有实体列表)。 我希望EF能够对所有关系进行映射并更新所有内容,但是看来EF仅会更新时间表模型,而忽略所有其他关联的实体。

这是正常现象还是我缺少了什么? 如果正常,那么完成我要尝试的操作的最佳实践是什么?

储存库更新代码...

    public void Update(T entity)
    {
        _dbSet.Attach(entity);
        _context.Entry(entity).State = EntityState.Modified;
    }

    public int Commit()
    {
        return _context.SaveChanges();
    }

我不确定是否会有所帮助,但这是我的模型

时间表

public class Timesheet
    {
        [Key]
        public int TimeSheetId { get; set; }

        public Guid Id { get; set; }

        public DateTime StartDate { get; set; }

        public DateTime EndDate { get; set; }

        public TimeSheetStatus TimeSheetStatus { get; set; }

        public int EmployeeId { get; set; }

        public virtual Employee Employee { get; set; }

        public virtual List<TimesheetLine> TimesheetLines { get; set; }
    }  

时间表行

public class TimesheetLine
{
    [Key]
    public int TimeSheetLineId { get; set; }

    public Guid CustomerId { get; set; }

    public string CustomerName { get; set; }

    public Guid EarningsId { get; set; }

    public virtual List<TimeSheetLineUnit> Units  { get; set; }

    public int TimeSheetId { get; set; }

    public virtual Timesheet Timesheet { get; set; }
}

TimeSheetLineUnit

public class TimeSheetLineUnit
{
    [Key]
    public int UnitId { get; set; }

    public decimal Hours { get; set; }

    [DisplayName("Notes")]
    public string Description { get; set; }

    public int Index { get; set; }

    public int TimeSheetLineId { get; set; }

    public virtual TimesheetLine TimesheetLine { get; set; }

}

为了在上面解释我的评论,我建议可能是问题所在。

当将数据库作为模型返回到服务器时,MVC要求“名称”属性唯一。

我将遍历子记录,如下所示:

@for (int i = 0; i < Model.Count; i++)
      {
        <tr>
          <td style="text-align: center;" class="Cell">
            @Html.CheckBoxFor(m => Model[i].Selected)
          </td>
          <td class="Cell">
            @Html.DisplayFor(m => Model[i].Name)
            @Html.HiddenFor(m => Model[i].Name)
          </td>
          <td class="Cell">
            @Html.DisplayFor(m => Model[i].AddressPhysical)
            @Html.HiddenFor(m => Model[i].AddressPhysical)
          </td>
          <td class="Cell">
            @Html.DisplayFor(m => Model[i].AddressPhysicalPostCode)
            @Html.HiddenFor(m => Model[i].AddressPhysicalPostCode)
          </td>
        </tr>
      }

注意:如果执行此操作,列表中的每个子行将具有其自己的唯一“名称”属性,并且MVC将能够唯一地标识每行数据,因此完整数据将被正确地传递回服务器中的模型。

这仅是一个示例,请尝试一下并看看如何进行。

对于EF更新存储库,请不要使用Attach首先将您的DbContext注入通用存储库中的构造中

  // my generic repository
  public class EntityBaseRepository<T>:IEntityBaseRepository<T> 
   where T :class , new()
 {
    //my context
    private DataContext dbContext;

     // use Dependency injection 
      public EntityBaseRepository(DataContext _dbContext)
   {
      this.dbContext = _dbContext;

   }


     //update method
       public void Update(T entity)
    {
        DbEntityEntry entry = this.dbContext.Entry(entity);
        entry.State = EntityState.Modified;
    }


 }

 // at the end call DbContext SaveChanges() from controller

请检查

也许您需要在更新方式中添加一些代码。

像这样:

public void Update(Timesheet timesheet)
{
    var existingParent = _dbContext.Parents
        .Where(p => p.Id == timesheet.Id)
        .Include(p => p.TimesheetLines)
        .SingleOrDefault();

    if (existingParent != null)
    {
        // Update parent
        _dbContext.Entry(existingParent).CurrentValues.SetValues(timesheet);

        // Delete TimesheetLines
        foreach (var existingChild in existingParent.TimesheetLines.ToList())
        {
            if (!timesheet.TimesheetLines.Any(c => c.Id == existingChild.Id))
                _dbContext.TimesheetLines.Remove(existingChild);
        }

        // Update and Insert TimesheetLines
        foreach (var childtimesheet in timesheet.TimesheetLines)
        {
            var existingChild = existingParent.TimesheetLines
                .Where(c => c.Id == childtimesheet.Id)
                .SingleOrDefault();

            if (existingChild != null)
                // Update child
                _dbContext.Entry(existingChild).CurrentValues.SetValues(childtimesheet);
            else
            {
                // Insert child
                var newChild = new Child
                {
                    Data = childtimesheet.Data,
                    //...
                };
                existingParent.TimesheetLines.Add(newChild);
            }
        }

        _dbContext.SaveChanges();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM