【问题标题】:Is there an easy way to make EntityFramework use SQL default values?有没有一种简单的方法可以让 EntityFramework 使用 SQL 默认值?
【发布时间】:2011-08-23 08:24:36
【问题描述】:

例如,我的大多数实体都有 DateCreated 和 DateModified 字段。这些的默认值在 SQL Server 中设置为 GetUtcDate()。

如果我尝试创建一个实体但不设置这些值,我会收到一个异常,指出它无法运行 SQL 插入,因为日期值超出了范围。这是有道理的,因为 C# 的默认日期是 1/1/0001,而 SQL Server 的最小日期是 1/1/1753。

那么有没有办法告诉 EF 使用 SQL Server 默认值,或者不尝试插入尚未设置的列?

【问题讨论】:

    标签: c# sql-server entity-framework


    【解决方案1】:

    你有没有试过在Entity中设置Property的DefaultValue?

    【讨论】:

    • 我真的希望避免遍历我的所有实体并调整每个属性的默认值。另外,这意味着如果我更改 SQL Server 中的默认值,我需要更改 EF 中的默认值并重新编译
    【解决方案2】:

    对于这些属性,您必须将 StoreGeneratedPattern 设置为 Identity(对于 DateCreated)和 Computed(对于 DataModified)。它在设计器中可用。一旦你这样做了,你就不能在你的应用程序中修改这些值——只有数据库可以设置这些属性。我写了这个some article,因为这个功能在VS2010 SP1之前有bug,但有报道说它有时仍然不起作用。

    【讨论】:

    • 谢谢,我在发布之前确实尝试过,但没有成功。我正在使用 VS 2010 Ultimate、SP1 和 EF4
    • 在这种情况下,请检查是否在 EDMX 文件的 CSDL 和 SSDL 部分设置了正确的存储生成模式(您必须将其作为 XML 打开),因为这是执行此操作的有效方法。
    • @Ladislav 我正在再试一次,但是我收到有关将非可空列映射到可空实体属性的错误。你知道它在说什么吗?
    • 这些属性是否可以为空?
    • @Rachel:在这种情况下,Computed 将无法正常工作,因为插入/更新 SQL 命令中不包含计算属性或身份属性。如果需要,您必须在应用程序中处理默认值。
    【解决方案3】:

    一种解决方案是使用 partial 覆盖您生成的 entitycontext 类。这将拦截 EF 上下文中所有实体类的插入/更新:

    public partial class MyEntities : ObjectContext
    {
        public override int SaveChanges(SaveOptions options)
        {
            this.DetectChanges();
    
            foreach (var insert in this.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added))
            {
                if (insert.Entity.HasProperty("DateCreated"))
                    insert.Entity.GetType().GetProperty("DateCreated").SetValue(insert.Entity, DateTime.UtcNow, null);
                if (insert.Entity.HasProperty("LastModified"))
                    insert.Entity.GetType().GetProperty("LastModified").SetValue(insert.Entity, DateTime.UtcNow, null);
            }
    
            foreach (var update in this.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Modified))
            {
                if (update.Entity.HasProperty("LastModified"))
                    update.Entity.GetType().GetProperty("LastModified").SetValue(update.Entity, DateTime.UtcNow, null);
            }
    
            return base.SaveChanges(options);
        }
    }
    

    或者做类似的事情,在您的日期戳字段上查找插入/更新并将它们从 ObjectStateEntries 集合中删除?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      • 2012-09-15
      相关资源
      最近更新 更多