我一直在按照以下教程尝试在我的MVC5应用程序中设置Code-First EntityFramework Migrations,然后使用一些示例数据为我的数据库设置以供使用: http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application
我的项目现在已经成功构建,我可以通过所有步骤来修改我的初始数据库:
- update-database -targetmigration:"0" -force -verbose
- *Delete Current Migrations
- add-migration InitialCreate
- update-database
当最后一个命令完成时,我的Seed
方法应该正在运行(我可以看到使用-verbose
参数创建的表)。但是,我的INV_Assets
表格中没有条目,其中应该有我当前播种所指定的条目。
有人可以提供一些输入,说明为什么我的Seed
方法似乎没有生效,虽然它似乎正在运行?
InventoryTracker.DAL.InventoryInitializer.cs :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using InventoryTracker.Models;
using InventoryTracker.DAL;
using WebMatrix.WebData;
namespace InventoryTracker.DAL
{
public class InventoryInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<InventoryTrackerContext>
{
InventoryTrackerContext context = new InventoryTrackerContext();
protected override void Seed(InventoryTrackerContext context)
{
List<INV_Locations> invLocs = getLocations();
invLocs.ForEach(s => context.INV_Locations.Add(s));
List<INV_Manufacturers> invManufacturers = getManufacturers();
invManufacturers.ForEach(s => context.INV_Manufacturers.Add(s));
List<INV_Models> invModels = getModels();
invModels.ForEach(s => context.INV_Models.Add(s));
List<INV_Statuses> invStatuses = getStatuses();
invStatuses.ForEach(s => context.INV_Statuses.Add(s));
List<INV_Types> invTypes = getTypes();
invTypes.ForEach(s => context.INV_Types.Add(s));
List<INV_Vendors> invVendors = getVendors();
invVendors.ForEach(s => context.INV_Vendors.Add(s));
List<INV_Assets> invAssets = getAssets();
invAssets.ForEach(s => context.INV_Assets.Add(s));
context.SaveChanges();
}
#region Seed Assets
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),
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;
}
#endregion
[Seed Locations]
[Seed Manufacturers]
#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 = 1,
model_description = "Sunblade 6000",
created_by = "Admin",
created_date = DateTime.Now
}
};
return testModels;
}
#endregion
[Seed Statuses]
[Seed Types]
[Seed Vendors]
}
}
InventoryTracker.DAL.InventoryTrackerContext.cs :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using InventoryTracker.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace InventoryTracker.DAL
{
public class InventoryTrackerContext : DbContext
{
public InventoryTrackerContext()
: base("InventoryTrackerContext")
{
}
public DbSet<INV_Assets> INV_Assets { get; set; }
public DbSet<INV_Models> INV_Models { get;set; }
public DbSet<INV_Manufacturers> INV_Manufacturers { get;set; }
public DbSet<INV_Types> INV_Types { get; set; }
public DbSet<INV_Locations> INV_Locations { get; set; }
public DbSet<INV_Vendors> INV_Vendors { get; set; }
public DbSet<INV_Statuses> INV_Statuses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
的Web.config :
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=301880
-->
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="InventoryTrackerContext" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\InventoryTrackerDBDev.mdf;Initial Catalog=InventoryTrackerDBDev;Integrated Security=True" providerName="System.Data.SqlClient" />
<!--<add name="PRISMContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=PrismDBdev5;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\PrismDBdev5.mdf" providerName="System.Data.SqlClient" />-->
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<!-- Active Directory Authentication - http://www.asp.net/mvc/overview/older-versions-1/security/authenticating-users-with-windows-authentication-cs -->
<authentication mode="Windows" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Extensibility.Web.RequestTracking.WebRequestTrackingModule, Microsoft.ApplicationInsights.Extensibility.Web" />
</httpModules>
<pages>
<namespaces>
<add namespace="GridMvc" />
</namespaces>
</pages></system.web>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
<remove name="ApplicationInsightsWebTracking" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Extensibility.Web.RequestTracking.WebRequestTrackingModule, Microsoft.ApplicationInsights.Extensibility.Web" preCondition="managedHandler" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebMatrix.Data" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<contexts>
<context type="InventoryTracker.DAL.InventoryTrackerContext, InventoryTracker">
<databaseInitializer type="InventoryTracker.DAL.InventoryInitializer, InventoryTracker" />
</context>
</contexts>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
修改:
好的,所以我出错的地方似乎是在错误的位置设置我的种子。它应该一直在InventoryTracer.Migrations.Configuration.cs
文件中......没有编入其中的种子...这就是为什么我在种子后没有得到任何插入的数据......:/
我现在已经在Configuration.cs
文件中将种子移植到正确的种子方法中,但我收到了错误:Invalid cast from 'Int32' to 'DateTime'.
Package Manager Console
的完整跟踪如下:
Running Seed method.
System.InvalidCastException: Invalid cast from 'Int32' to 'DateTime'.
at System.Int32.System.IConvertible.ToDateTime(IFormatProvider provider)
at System.Convert.ToDateTime(Int32 value)
at InventoryTracker.Migrations.Configuration.getAssets() in c:\James-Projects\InventoryTracker\InventoryTracker\Migrations\Configuration.cs:line 57
at InventoryTracker.Migrations.Configuration.Seed(InventoryTrackerContext context) in c:\James-Projects\InventoryTracker\InventoryTracker\Migrations\Configuration.cs:line 47
at System.Data.Entity.Migrations.DbMigrationsConfiguration`1.OnSeed(DbContext context)
at System.Data.Entity.Migrations.DbMigrator.SeedDatabase()
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase()
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
Invalid cast from 'Int32' to 'DateTime'.
我不太确定发生投射错误的位置,因为Configuration.cs
的第47/57行分别是:
47 - List<INV_Assets> invAssets = getAssets();
57 - List<INV_Assets> testAssets = new List<INV_Assets>
我的猜测是围绕第71行 - acquired_date = Convert.ToDateTime(10212014),
旋转。
有人想过如何解决这个问题?
Configuration.cs :
namespace InventoryTracker.Migrations
{
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Web;
using InventoryTracker.Models;
using InventoryTracker.DAL;
using WebMatrix.WebData;
internal sealed class Configuration : DbMigrationsConfiguration<InventoryTracker.DAL.InventoryTrackerContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(InventoryTracker.DAL.InventoryTrackerContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
List<INV_Locations> invLocs = getLocations();
invLocs.ForEach(s => context.INV_Locations.Add(s));
List<INV_Manufacturers> invManufacturers = getManufacturers();
invManufacturers.ForEach(s => context.INV_Manufacturers.Add(s));
List<INV_Models> invModels = getModels();
invModels.ForEach(s => context.INV_Models.Add(s));
List<INV_Statuses> invStatuses = getStatuses();
invStatuses.ForEach(s => context.INV_Statuses.Add(s));
List<INV_Types> invTypes = getTypes();
invTypes.ForEach(s => context.INV_Types.Add(s));
List<INV_Vendors> invVendors = getVendors();
invVendors.ForEach(s => context.INV_Vendors.Add(s));
List<INV_Assets> invAssets = getAssets();
invAssets.ForEach(s => context.INV_Assets.Add(s));
context.SaveChanges();
}
#region Seed Assets
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),
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;
}
#endregion
#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 = 1,
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 = 1,
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 = 1,
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 = 1,
vendor_name = "Samsung",
created_by = "Admin",
created_date = DateTime.Now
}
};
return testVendors;
}
#endregion
}
}
EDIT2 :
我认为通过将Invalid cast from 'Int32' to 'DateTime'.
更改为acquired_date = Convert.ToDateTime(10212014)
,我已经处理了acquired_date = DateTime.ParseExact("10212014", "MMddyyyy", CultureInfo.InvariantCulture)
,但现在我遇到了新的错误。< / p>
当我运行update-database
命令时,我的Seed方法现在失败,错误为Ambiguous match found
。将以下代码放在Seed()
的最顶部,我试图获取更多信息:
if (System.Diagnostics.Debugger.IsAttached == false)
{
System.Diagnostics.Debugger.Launch();
}
当代码到达invAssets.ForEach(s => context.INV_Assets.Add(s));
时,我启动的调试器会捕获An exception of type 'System.Reflection.AmbiguousMatchException' occurred in mscorlib.dll but was not handled in user code. Additional information: Ambiguous match found.
有人对导致这种情况的原因有所了解吗?我可以看到Ambiguous
错误的可能性是我添加了多个测试记录,但此时我只有一个记录被INV_Assets
播种。
根据Soren Gustenhoff建议,我更改了Foreach => Add()
以使用.AddRange()
并在调用context.SaveChanges()
之前添加了初步getAssets()
,但这只会导致调用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.
CODE : context.INV_Types.AddRange(invTypes); //类型&#39; System.Data.Entity.Infrastructure.DbUpdateException异常 //context.SaveChanges(); 列出invVendors = getVendors(); context.INV_Vendors.AddRange(invVendors); context.SaveChanges(); //使用模糊错误评论此标志[getVendors()]?
List<INV_Assets> invAssets = getAssets();
context.INV_Assets.AddRange(invAssets);
context.SaveChanges();
回到最后只有一个context.SaveChanges()
,我的getVendors()
现在首先标记为AmbiguousMatchException
???
答案 0 :(得分:3)
您在尚未创建的INV_Assets中设置关系。
EF上下文不会创建主键,直到您运行saveChanges
我建议你这样做
List<INV_Types> invTypes = getTypes();
invTypes.ForEach(s => context.INV_Types.Add(s));
context.INV_Types.AddRange(invTypes);
List<INV_Vendors> invVendors = getVendors();
context.INV_Vendors.AddRange(invVendors);
context.SaveChanges();
List<INV_Assets> invAssets = getAssets();
context.INV_Assets.AddRange(invAssets);
context.SaveChanges();
顺便说一下。注意addRange而不是foreach - &gt;添加。
聚苯乙烯。 有关调试种子方法的信息,请参阅:Debugging Package Manager Console Update-Database Seed Method
我希望有所帮助:)