【问题标题】:EF Code First Pre-filter datetime on insert / updateEF Code First 在插入/更新时预过滤日期时间
【发布时间】:2017-01-17 15:25:40
【问题描述】:

按照这些问题的思路:

  1. 'datetime2' error when using entity framework in VS 2010 .net 4.0
  2. How to fix the datetime2 out-of-range conversion error using DbContext and SetInitializer?

我尝试使用代码首先基于我不拥有的模型生成数据库。 IE。我无法修改模型。 (我正在使桌面应用程序与服务器应用程序同步。)

我了解 C# 中的 DateTime 值在转换为 SqlDateTime 时具有无效的 MinDate。此外,从 Entity Framework 创建的 SQL Express 实例不支持datetime2。我尝试使用约定应用具有默认值的过滤器:

this.Properties<DateTime>()
                .Configure(o => o.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed).HasColumnAnnotation("SqlDefaultValue", "GETDATE()"));

但是,当我这样做时,我收到错误 Cannot insert the value NULL into column 'CreatedDate', table 'blahblahblah.Companies'; column does not allow nulls. INSERT fails.

我不确定我是否理解该错误消息,因为这些值永远不会为空。但我猜是因为DatabaseGeneratedOptioncomputed,所以没有设置值。

到目前为止,这些选项都不适用于日期时间。如果有办法预过滤插入和更新,我可以检查日期时间值并将它们的值设置为 SqlDateTime 最小值。但是,我的 Google foo 没有为该类型的操作返回任何结果。如果没有办法做到这一点,我可以只做一个辅助函数,使用反射来适当地自动调整所有日期时间对象。

【问题讨论】:

    标签: c# entity-framework datetime


    【解决方案1】:

    我最终编写了一个辅助函数来预先更新日期时间值。

    public static class DateTimeSwitch
    {
        public static void DateTimeToSqlDateTime(this object obj)
        {
            Type objType = obj.GetType();
    
            if (typeof(IEnumerable).IsAssignableFrom(objType))
            {
                IEnumerable enumerable = (IEnumerable)obj;
                if (enumerable != null)
                {
                    foreach (object c in enumerable)
                    {
                        if (c != null)
                            c.DateTimeToSqlDateTime();
                    }
                }
            }
            else
            {
                PropertyInfo[] properties = objType.GetProperties();
    
                foreach (PropertyInfo property in properties)
                {
                    if (typeof(DateTime).IsAssignableFrom(property.PropertyType))
                    {
                        // Get the value, adjust it.
                        DateTime value = (DateTime)property.GetValue(obj, null);
                        if (value < (DateTime)SqlDateTime.MinValue)
                        {
                            property.SetValue(obj, (DateTime)SqlDateTime.MinValue, null);
                        }
                    }
                    else if (!property.PropertyType.IsPrimitive && typeof(String) != property.PropertyType && typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
                    {
                        IEnumerable enumerable = (IEnumerable)property.GetValue(obj, null);
                        if (enumerable != null)
                        {
                            foreach (object c in enumerable)
                            {
                                if (c != null)
                                    c.DateTimeToSqlDateTime();
                            }
                        }
                    }
                    else if (!property.PropertyType.IsPrimitive)
                    {
                        if (property.PropertyType.Assembly == objType.Assembly)
                        {
                            var value = property.GetValue(obj, null);
                            if (value != null) value.DateTimeToSqlDateTime();
                        }
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 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
      相关资源
      最近更新 更多