【问题标题】:MVC EntityFramework Code-First Migrations - Seed() Failing with DbUpdateException?MVC EntityFramework 代码优先迁移 - Seed() 因 DbUpdateException 而失败?
【发布时间】:2015-01-16 15:18:05
【问题描述】:

我正在开发一个有点简单的 InventoryTracker MVC5 应用程序,其中我在将 LocalDatabase 设置为 Seed() 时遇到了一些问题。

当我在下面的代码上运行update-database 命令时,我在context.INV_Types.AddRange(invTypes) 行收到如下异常:

An exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll but was not handled in user code. Additional information: An error occurred while updating the entries. See the inner exception for details.

内部异常The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated.


代码

internal sealed class Configuration : DbMigrationsConfiguration<InventoryTracker.DAL.InventoryTrackerContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(InventoryTracker.DAL.InventoryTrackerContext context)
    {
        if (System.Diagnostics.Debugger.IsAttached == false)
        {
            System.Diagnostics.Debugger.Launch();
        }

        List<INV_Locations> invLocs = getLocations();
        context.INV_Locations.AddRange(invLocs);
        List<INV_Manufacturers> invManufacturers = getManufacturers();
        context.INV_Manufacturers.AddRange(invManufacturers);
        List<INV_Models> invModels = getModels();
        context.INV_Models.AddRange(invModels);
        List<INV_Statuses> invStatuses = getStatuses();
        context.INV_Statuses.AddRange(invStatuses);
        List<INV_Types> invTypes = getTypes();
        context.INV_Types.AddRange(invTypes); // EXCEPTION?
        List<INV_Vendors> invVendors = getVendors();
        context.INV_Vendors.AddRange(invVendors);

        context.SaveChanges(); // Was told I needed to Save the other seeds before the Assets to ensure primary keys are created in the other tables?

        List<INV_Assets> invAssets = getAssets();
        context.INV_Assets.AddRange(invAssets);

        context.SaveChanges();
    }

    private List<INV_Types> getTypes()
    {
        List<INV_Types> testTypes = new List<INV_Types>
        {
            new INV_Types
            {
                Id = 1,
                type_description = "Server",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Types
            {
                Id = 2,
                type_description = "IP Phone",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Types
            {
                Id = 3,
                type_description = "Monitor",
                created_by = "Admin",
                created_date = DateTime.Now
            }
        };
        return testTypes;
    }

    private List<INV_Assets> getAssets()
        {
            List<INV_Assets> testAssets = new List<INV_Assets>
            {
              new INV_Assets
              {
                Id = 1,
                ip_address = "10.10.135.38",
                mac_address = "10.10.177.44",
                note = "",
                owner = "John Smith",
                cost = 35,
                po_number = "G348",
                invoice_number = 1447,
                serial_number = "JX14582Y",
                asset_tag_number = "293548195023",
                //acquired_date = Convert.ToDateTime(10212014),
                acquired_date = DateTime.ParseExact("10212014", "MMddyyyy", CultureInfo.InvariantCulture),
                disposed_date = null,
                created_by = "Admin",
                created_date = DateTime.Now,
                Location_Id = 1,
                Manufacturer_Id = 1,
                Model_Id = 1,
                Status_Id = 2,
                Type_Id = 3,
                Vendor_Id = 3
            }
        };
        return testAssets;
    }

是否有人对我的Seed() for INV_Types 的结构中可能导致此问题的原因有任何想法?

我认为这可能是我需要在getTYpes() 之前将我的更改保存到上下文中,但是在.AddRange(invStatuses) 之后添加context.SaveChanges() 只会导致与新的context.SaveChanges() 相同的错误??

如果有人看到我忽略的东西,我在下面包含了我的其他种子方法:

    #region Seed Locations
    private List<INV_Locations> getLocations()
    {
        List<INV_Locations> testLocations = new List<INV_Locations>
        {
            new INV_Locations
            {
                Id = 1,
                location_dept = "IT",
                location_room = "Server",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Locations
            {
                Id = 2,
                location_dept = "Break Room",
                location_room = "Kitchen",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Locations
            {
                Id = 3,
                location_dept = "Accounting",
                location_room = "Conference",
                created_by = "Admin",
                created_date = DateTime.Now
            }
        };
        return testLocations;
    }
    #endregion

    #region Seed Manufacturers
    private List<INV_Manufacturers> getManufacturers()
    {
        List<INV_Manufacturers> testManufacturers = new List<INV_Manufacturers>
        {
            new INV_Manufacturers
            {
                Id = 1,
                manufacturer_description = "Samsung",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Manufacturers
            {
                Id = 2,
                manufacturer_description = "MITEL",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Manufacturers
            {
                Id = 3,
                manufacturer_description = "Oracle",
                created_by = "Admin",
                created_date = DateTime.Now
            }
        };
        return testManufacturers;
    }
    #endregion

    #region Seed Models
    private List<INV_Models> getModels()
    {
        List<INV_Models> testModels = new List<INV_Models>
        {
            new INV_Models
            {
                Id = 1,
                model_description = "XTERAV12",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Models
            {
                Id = 2,
                model_description = "5330",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Models
            {
                Id = 3,
                model_description = "Sunblade 6000",
                created_by = "Admin",
                created_date = DateTime.Now
            }
        };
        return testModels;
    }
    #endregion

    #region Seed Statuses
    private List<INV_Statuses> getStatuses()
    {
        List<INV_Statuses> testStatuses = new List<INV_Statuses>
        {
            new INV_Statuses
            {
                Id = 1,
                status_description = "AVAILABLE",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Statuses
            {
                Id = 2,
                status_description = "SIGNEDOUT",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Statuses
            {
                Id = 3,
                status_description = "RECYCLED",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Statuses
            {
                Id = 4,
                status_description = "AUCTIONED",
                created_by = "Admin",
                created_date = DateTime.Now
            }
        };
        return testStatuses;
    }
    #endregion

    #region Seed Types
    private List<INV_Types> getTypes()
    {
        List<INV_Types> testTypes = new List<INV_Types>
        {
            new INV_Types
            {
                Id = 1,
                type_description = "Server",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Types
            {
                Id = 2,
                type_description = "IP Phone",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Types
            {
                Id = 3,
                type_description = "Monitor",
                created_by = "Admin",
                created_date = DateTime.Now
            }
        };
        return testTypes;
    }
    #endregion

    #region Seed Vendors
    private List<INV_Vendors> getVendors()
    {
        List<INV_Vendors> testVendors = new List<INV_Vendors>
        {
            new INV_Vendors
            {
                Id = 1,
                vendor_name = "Oracle",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Vendors
            {
                Id = 2,
                vendor_name = "Centriq",
                created_by = "Admin",
                created_date = DateTime.Now
            },
            new INV_Vendors
            {
                Id = 3,
                vendor_name = "Samsung",
                created_by = "Admin",
                created_date = DateTime.Now
            }
        };
        return testVendors;
    }
    #endregion

编辑:

正如IronMan84 指出的那样,我错误地将每个实体的多个实例复制粘贴到具有相同Id 值(例如1、2、1 而不是1、2、3)的位置。但是,错误仍然存​​在,除了现在在以下行:

        context.INV_Vendors.AddRange(invVendors);

        context.SaveChanges(); // DbUpdateException!

        List<INV_Assets> invAssets = getAssets();

EDIT2:在最初列出的错误中添加了内部异常详细信息。 The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated.

EDIT3:为了更好地诊断问题,我尝试在每个.AddRange() 调用之后添加context.SaveChanges(),但context.INV_Locations.AddRange(invLocs) 之后的第一个实例会导致相同的错误:

An exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll but was not handled in user code. Additional information: An error occurred while updating the entries. See the inner exception for details.

内部异常The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated.

我只能想象这是引用我的getLocations()[created_date] 值设置为DateTime.Now,但我不确定问题是什么?

在我的模型中,我将属性定义为:

    [Required]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
    public DateTime created_date { get; set; }

【问题讨论】:

  • 内部异常是怎么说的?

标签: c# asp.net-mvc entity-framework asp.net-mvc-5 entity-framework-migrations


【解决方案1】:

getTypes() 方法中的 2 个类型的 Id 值为 1。EF 不喜欢这种冲突,因此会崩溃。

编辑:您在 cmets (The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated.) 中提到的错误仅由具有 DateTime 属性的对象引起,该属性的当前值设置为 1753 年 1 月 1 日之前的日期(很可能已设置到DateTime.MinValue,即 1/1/0001)。

造成这种情况的原因是 EF 将 C# 的 DateTime 类型映射到 SQL 的 datetime 类型(而不是 datetime2,它可以追溯到 1/1/0001),它具有上述最小日期要求。当您尝试保存日期为 1/1/1753 之前 的对象时,SQL 认为您正在尝试将 datetime2 保存在类型为 datetime 的列中并炸毁。

解决方案是对其进行调试并找出哪些记录的属性仍设置为错误日期(如DateTime.MinValue)并调整代码以相应地编辑这些属性。

【讨论】:

  • 感谢钢铁侠的回复。我陷入了旧的复制粘贴错误...我曾希望这能解决我的问题,但现在我在AddRange(invVendors) 之后和getAssets() 调用之前在context.SaveChanges() 收到相同的错误(请参阅上面的编辑为了清楚起见)。
  • 内部异常是怎么说的?
  • 您的Location 课程中还有其他DateTime 属性吗?因为那些自动设置为DateTime.MinValue
  • 您需要设置它才能保存记录。即使您不设置它,EF 也会尝试保存它(除非它可以为空)
  • 您必须将其设置为某个值。我会推荐与CreatedDate 相同的值。
猜你喜欢
  • 2015-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
  • 2019-11-20
  • 2013-10-03
  • 1970-01-01
  • 2016-05-26
相关资源
最近更新 更多