【问题标题】:Entity Framework MapToStoredProcedures Update and update not every fields of an object实体框架 MapToStoredProcedures 更新和更新不是对象的每个字段
【发布时间】:2016-04-24 12:28:18
【问题描述】:

我有一个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();

对于不更新“CreatedOn”字段,我将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 而不更新每一列?

【问题讨论】:

  • 您是否试图阻止人们更改“CreatedOn”属性?有什么例外?如果您确定.IsModified == true 或以某种方式获取现有条目并重置为原始值(如果在事务中存在大量开销和死锁的危险),我认为您可能必须抛出异常。但是您可能想要使用数据库检查约束或其他能够更好地处理所需情况的东西。或者告诉 EF 该列是 DatabaseGeneratedOption.Computed 并将其默认设置为插入时的 GetDate()。

标签: entity-framework stored-procedures mapping


【解决方案1】:

你可以让数据库为你做设置值的工作吗?

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 选项告诉 Entity Framework 它不需要将该参数发送到您的 proc,因为数据库将为该列/属性生成值。您必须记住,存储的 proc 必须在其结果集中返回该列 - 但它可以只使用该列的默认值,该值是在 proc 中生成的。

如果您这样做,甚至不需要覆盖 SaveChanges 以设置默认值,该值将在 SaveChanges() 之后为您设置。

仅供参考:此处为实体框架 6.x。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多