MVC EntityFramework代码优先迁移 - Seed()失败DbUpdateException?

时间:2015-01-06 16:31:19

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

我正在开发一个简单的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.


CODE

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() INV_Types getTYpes()的结构中可能导致此问题的人有任何想法?

我认为可能需要在context.SaveChanges()之前将更改保存到上下文中,但在.AddRange(invStatuses)之后添加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 ??

如果有人看到我忽视的东西,我已经在下面提供了我的其他种子方法来帮助我们:

Id

修改

正如IronMan84指出的那样,我错误地将其复制粘贴到我拥有相同 context.INV_Vendors.AddRange(invVendors); context.SaveChanges(); // DbUpdateException! List<INV_Assets> invAssets = getAssets(); 值的每个实体的几个实例的位置(例如,1,2,1而不是1,2, 3)。但是,错误仍然存​​在,除非现在在以下行:

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

EDIT2 :在最初列出的错误中添加了内部异常详细信息。 context.SaveChanges()

EDIT3 :为了更好地诊断问题,我尝试在每次.AddRange()次调用后添加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; } ,但我不确定问题是什么?

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

{{1}}

1 个答案:

答案 0 :(得分:2)

getTypes()方法中的2个类型的Id值为1. EF不喜欢该冲突,因此会爆炸。

编辑:您在评论中提到的错误(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)并调整代码以相应地编辑这些属性。