我有一个BaseEntity
:
public class BaseEntity : IBaseEntity
{
[ScaffoldColumn(false)]
public string ID { get; set; }
[ScaffoldColumn(false)]
public DateTime CreatedOn { get; set; }
[ScaffoldColumn(false)]
public bool Deleted { get; set; }
}
和个人实体:
public class People : BaseEntity
{ //Fields }
我想使用存储过程进行更新、插入、删除,所以在我的上下文中这样做:
modelBuilder.Entity<People>()
.MapToStoredProcedures();
对于不更新"创建时间"字段,我将SaveChanges
覆盖为:
public override int SaveChanges()
{
var modifiedEntries = ChangeTracker.Entries()
.Where(x => x.Entity is IBaseEntity
&& (x.State == System.Data.Entity.EntityState.Added || x.State == System.Data.Entity.EntityState.Modified));
foreach (var entry in modifiedEntries)
{
IBaseEntity entity = entry.Entity as IBaseEntity;
if (entity != null)
{
DateTime now = DateTime.Now;
if (entry.State == System.Data.Entity.EntityState.Added)
{
entity.CreatedOn = now;
}
else
{
base.Entry(entity).Property(x => x.CreatedOn).IsModified = false;
}
}
}
return base.SaveChanges();
}
但是当进行更新时,将运行存储过程并为@createdOn
参数设置默认值并返回异常。
如何使用MapToStoredProcedures
并更新不是每个列?
你能让数据库为你设置值吗?
public class BaseEntity : IBaseEntity
{
[ScaffoldColumn(false)]
public string ID { get; set; }
[ScaffoldColumn(false)]
[DatabaseGeneratedOption(DatabaseGeneratedOption.Computed)]
public DateTime CreatedOn { get; set; }
[ScaffoldColumn(false)]
public bool Deleted { get; set; }
}
然后你的 UPDATE 过程甚至根本不应该传递参数。在 UPDATE 存储过程中,将 CreatedOn 的值设置为 GETDATE()、GETUTCDATE(),或者如果您未使用 SQL Server,则在数据库中设置日期值的任何值。
这里的想法是,设置 DatabaseGenerated 选项告诉实体框架它不需要将该参数发送到您的进程,因为数据库将为该列/属性生成值。您必须记住,存储的 proc 必须在其结果集中返回该列 - 但它只能使用该列的默认值,该值是在 proc 中生成的。
如果这样做,甚至不需要覆盖 SaveChanges 来设置默认值,该值将在 SaveChanges() 之后为您设置。
仅供参考:此处为实体框架 6.x。