我刚开始尝试使用EF4代码,今天早上我在一个单独的类库中创建了POCO,数据上下文和初始化程序类,我相信它是常规的锅炉板类型代码。我在MVC3应用程序中引用该类,并在Global.asax中设置初始化程序。在运行应用程序时,我注意到以下问题
1.没有在任何地方创建数据库(然后我在web.config中添加一个条目,用于以Context类命名的连接字符串,仍然没有结果)
2.当我尝试访问初始值时,我得到一个空错误,显然是因为没有数据。
任何人都可以帮我指点如何让这件事工作(如果我整个圣诞节都花了整整一天学习这个而且我仍然无法让它工作,那将是一种耻辱:()
由于
附:我尝试插入断点并点击app初始化方法,但它始终没有在初始化程序中点击Seed方法,即使我在那里添加了断点!
谢谢。
初始化程序类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using F2AController.Models;
namespace F2AController.DataObjects
{
public class F2AInitializer : DropCreateDatabaseAlways<F2AContext>
{
protected override void Seed(F2AContext context)
{
var countries = new List<Country>
{
new Country(){ CountryName="Germany", Active = true},
new Country(){ CountryName="Britain", Active = true}
};
countries.ForEach(s => context.Countries.Add(s));
context.SaveChanges();
var providers = new List<Providers>()
{
new Providers(){ ProviderName="InfoBip", ContactDetails="Rturo Manovic", Active=true, MessageRates= new List<ProviderRates>(){new ProviderRates(){ CountryId=1, DateCreated=DateTime.Now, DateModified=DateTime.Now, Rate=0.05M, Active=true}}}
};
providers.ForEach(p => context.Providers.Add(p));
context.SaveChanges();
var usermobiles = new List<MobileTerminal>()
{
new MobileTerminal(){ Active= true, Credits=200, DateCreated=DateTime.Now, MSISDN="4477565444865"}
};
usermobiles.ForEach(u => context.MobileTerminals.Add(u));
context.SaveChanges();
}
}
}
上下文类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
namespace F2AController.Models
{
public class F2AContext : DbContext
{
public DbSet<Country> Countries;
public DbSet<MobileTerminal> MobileTerminals;
public DbSet<Providers> Providers;
public DbSet<ProviderRates> ProviderRates;
public DbSet<Property> Properties;
public DbSet<ShortMessage> ShortMessages;
public DbSet<UserProperties> UserProperties;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
}
Global.asax App初始化方法
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
Database.DefaultConnectionFactory = new SqlConnectionFactory(ConfigurationManager.ConnectionStrings["F2AContext"].ConnectionString);
Database.SetInitializer<F2AContext>(new F2AInitializer());
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
答案 0 :(得分:4)
Eureka..finally!
在搜索解决方案时,我发现了这篇文章Entity Framework Database.SetInitializer simply not working
应用解决方案建议在那里强制我的数据库创建像我预期的那样在启动时工作,但是在运行种子代码时,它抛出了一个空指针异常。在调查时,我意识到任何从Context类引用DBSet集合的尝试都会产生相同的异常。进一步检查我意识到,而不是使用
public DbSet<MobileTerminal> MobileTerminals { get; set; }
我用过
public DbSet<MobileTerminal> MobileTerminals;
这意味着我没有得到任何隐式对象初始化,因此空指针异常。我删除了强制初始化代码并再次运行应用程序,这次种子代码没有运行,直到我访问了一个实际查询数据上下文并且运行完美的页面。
显然,由于延迟加载,初始化代码在实际需要之前不会运行,即第一次在应用程序中查询数据上下文。
我希望这可以帮助将来遇到同样问题的人。
答案 1 :(得分:1)
我想在首先使用类库代码时分享另一个问题。偶然发现了这篇文章。我在代码库项目中首先使用了代码POCO和DataContext类,并希望使用此项目来创建我的代码第一个数据库。我发现有一个-ProjectName标志,可以在创建数据库时指定要查找的类库项目。
add-migration -Name 'InitialCreate' -ProjectName 'MyProject.Data'
update-database -ProjectName 'MyProject.Data'
答案 2 :(得分:0)
问题可能出在您在web.config中使用的连接字符串。
对于SQL CE,请使用以下
<add name="YourContext"
connectionString="Data Source=|DataDirectory|yourDB.sdf"
providerName="System.Data.SqlServerCe.4.0"/>
对于SQL Express,请使用以下
<add name="YourContext"
connectionString="Data source=.\SQLEXPRESS;Integrated Security=True;Initial Catalog=YourDatabase;"
providerName="System.Data.SqlClient" />
我想这应该会让事情奏效。
另外,我认为你应该看一下这篇文章EF Code First DB Initialization Using Web.Config。最好从web.config而不是从global.asax文件
初始化数据库