MVC EntityFramework Code-First Migrations - Seed() 因 DbUpdat

本文关键字:DbUpdat Seed EntityFramework Code-First Migrations MVC | 更新日期: 2023-09-27 18:36:31

>我正在开发一个有点简单的InventoryTracker MVC5应用程序,其中我在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()结构中可能导致这种情况的原因有任何想法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; }

MVC EntityFramework Code-First Migrations - Seed() 因 DbUpdat

getTypes()方法中的 2 个类型具有 1 Id值。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 ),并相应地调整代码以编辑这些属性。