Reputation: 3944
I've been following the below tutorial in an attempt to set up Code-First EntityFramework Migrations in my MVC5 App and then Seed my database with some sample data for use: 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
My project is now successfully building, and I can go through all of the steps to modify my initial database:
- update-database -targetmigration:"0" -force -verbose
- *Delete Current Migrations
- add-migration InitialCreate
- update-database
When the last command completes, my Seed
method is supposedly being ran (and I can see the tables being created using the -verbose
parameter). However, there is no entry in my INV_Assets
table where there should be one as specified by my current seeding.
Can anyone offer some input as to why my Seed
method does not appear to be taking effect, though it seems to be running?
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>
EDIT:
Ok, so it seems where I was going wrong was setting up my Seed in the wrong location. It should have all along been in the InventoryTracer.Migrations.Configuration.cs
file... which had no seeding coded into it... which is why I was not getting any inserted data after Seed... :/
I've now moved seeding into the proper seed method in the Configuration.cs
file, but I'm getting an error: Invalid cast from 'Int32' to 'DateTime'.
The full trace from Package Manager Console
is as follows:
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'.
I'm not quite sure where the cast error is occurring though, as Lines 47/57 of my Configuration.cs
respectively are:
47 - List<INV_Assets> invAssets = getAssets();
57 - List<INV_Assets> testAssets = new List<INV_Assets>
My guess would be it is revolving around line 71 - acquired_date = Convert.ToDateTime(10212014),
.
Anyone have thoughts on how to resolve this?
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:
I think I've got the Invalid cast from 'Int32' to 'DateTime'.
taken care of by changing acquired_date = Convert.ToDateTime(10212014)
to acquired_date = DateTime.ParseExact("10212014", "MMddyyyy", CultureInfo.InvariantCulture)
, but now I have a new error.
When I run the update-database
command, my Seed method now fails with error Ambiguous match found
. By placing the following code at the topmost part of my Seed()
I tried to get some more information:
if (System.Diagnostics.Debugger.IsAttached == false)
{
System.Diagnostics.Debugger.Launch();
}
When the code reaches invAssets.ForEach(s => context.INV_Assets.Add(s));
the Debugger that I launched catches with An exception of type 'System.Reflection.AmbiguousMatchException' occurred in mscorlib.dll but was not handled in user code. Additional information: Ambiguous match found.
Anyone have thoughts on what is causing this? I could see potential of an Ambiguous
error were I adding more than one test record, but at this time I only have the one record being seeded for INV_Assets
.
Following Soren Gustenhoff suggestions, I changed the Foreach => Add()
to use .AddRange()
and added a preliminary context.SaveChanges()
before the getAssets()
is called, but that only resulted in the following when the AddRange(invTypes)
is called?
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); // exception of type 'System.Data.Entity.Infrastructure.DbUpdateException //context.SaveChanges(); List invVendors = getVendors(); context.INV_Vendors.AddRange(invVendors); context.SaveChanges(); // Commenting this flags [getVendors()] with the Ambiguous Error?
List<INV_Assets> invAssets = getAssets();
context.INV_Assets.AddRange(invAssets);
context.SaveChanges();
Going back to only having the one context.SaveChanges()
at the end, my getVendors()
is flagging with the AmbiguousMatchException
first now???
Upvotes: 0
Views: 1430
Reputation: 41
You setup relations in your INV_Assets that haven't been created yet.
EF Context won't create primary keys untill you have run saveChanges
i would recommend you to do this
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();
Btw. Notice the addRange instead of foreach -> add.
Ps. For debugging seed method, see this: Debugging Package Manager Console Update-Database Seed Method
I hope that helped :)
Upvotes: 3