MVC EntityFramework 代码优先迁移 - Seed() 因 DbUpdateException 而失败?
MVC EntityFramework Code-First Migrations - Seed() Failing with DbUpdateException?
我正在开发一个有点简单的 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()
,但是 [= 之后的第一个实例20=] 导致相同的错误:
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; }
您的 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),它有上面提到的最低日期要求。当您尝试保存日期为 before 的对象时 1/1/1753 SQL 认为您正在尝试将 datetime2
保存在列中datetime
类型并爆炸。
解决方案是对其进行调试,找出哪些记录的属性仍设置为错误日期(如 DateTime.MinValue
),然后调整代码以相应地编辑这些属性。
我正在开发一个有点简单的 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()
,但是 [= 之后的第一个实例20=] 导致相同的错误:
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; }
您的 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),它有上面提到的最低日期要求。当您尝试保存日期为 before 的对象时 1/1/1753 SQL 认为您正在尝试将 datetime2
保存在列中datetime
类型并爆炸。
解决方案是对其进行调试,找出哪些记录的属性仍设置为错误日期(如 DateTime.MinValue
),然后调整代码以相应地编辑这些属性。