我在我的域模型中有这个实体服务,有两个日期时间类型属性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;
}
}
答案 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
的属性设置为未修改,并且会抛出异常。