更新标记实体datetime属性时保持不变

时间:2011-09-22 19:54:01

标签: asp.net-mvc-3 entity-framework-4 ef-code-first

我在我的域模型中有这个实体服务,有两个日期时间类型属性entrydate和updatedon。

当编辑视图中的用户进行任何更改并提交表单时,我希望将回发/修改对象的entrydate属性标记为未更改,以便在执行更新时不能覆盖entrydate。

public class Service
{
    public int ServiceID
    {
        get;
        set;

    }
    [Required(ErrorMessage="Please enter Name")]
    public string Name
    {
        get;
        set;
    }

    [Required(ErrorMessage="Please enter the duration for the service")]
    public short Duration
    {
        get;
        set;
    }


    [DataType(DataType.Date)]
    public DateTime EntryDate
    {
        get;
        set;
    }

    [DataType(DataType.Date)]
    public DateTime UpdatedOn
    {
        get;
        set;
    }



    public decimal Cost
    {
        get; set;

    }
}

持久化更改为db的存储库方法如下:

 public void InsertOrUpdate(Service service)
    {
        if (service.ServiceID == default(int)) {
            // New entity
            context.Services.Add(service);
        } else {
            // Existing entity

            context.Entry(service).State = EntityState.Modified;
        }
    }

1 个答案:

答案 0 :(得分:1)

您可以从数据库重新加载原始实体:

else {
    // Existing entity
    var serviceInDb = context.Services.Find(service.ServiceID);
    service.EntryDate = serviceInDb.EntryDate;
    context.Entry(serviceInDb).CurrentValues.SetValues(service);
}

稍后调用SaveChanges时,只有真正更改过的属性的UPDATE语句才会被发送到数据库(对其他未更改的属性也有好处)。

或者只是重新加载EntryDate

else {
    // Existing entity
    var entryDateInDb = context.Services
        .Select(s => s.EntryDate)
        .Single(s => s.ServiceID == service.ServiceID);
    service.EntryDate = entryDateInDb;
    context.Entry(service).State = EntityState.Modified;
}

另一种有效而又丑陋的方法是:

context.Services.Attach(service); // thanks to user202448, see comments

context.Entry(service).Property(s => s.Name).IsModified = true;
context.Entry(service).Property(s => s.Duration).IsModified = true;
context.Entry(service).Property(s => s.UpdatedOn).IsModified = true;
context.Entry(service).Property(s => s.Cost).IsModified = true;

因此,不要将EntryDate属性设置为已修改,而是将所有其他属性逐个设置。

想到的方法......

context.Entry(service).State = EntityState.Modified;
context.Entry(service).Property(s => s.EntryDate).IsModified = false;

...遗憾的是不起作用,因为不支持将已经标记为Modified的属性设置为未修改,并且会抛出异常。