实体框架代码首先在类库
本文关键字:类库 框架 代码 实体 | 更新日期: 2023-09-27 18:18:57
我今天早上刚开始尝试EF4代码,我在一个单独的类库中创建了我的POCO,数据上下文和初始化器类,我相信这是常规的锅炉板类型代码。我在mvc应用程序中引用该类,并在Global.asax中设置初始化器。在运行应用程序时,我注意到以下问题
1. 没有数据库是创建在任何地方(然后我在网络上添加一个条目。配置以Context类命名的连接字符串,仍然没有结果)
2. 当我试图访问初始化的值时,我得到一个null错误,显然是因为没有数据。
谁能帮我指点一下如何让这个东西工作(如果我花了整个圣诞节学习这个,我仍然不能让它工作,那将是一个遗憾:)由于
p.s.我试着插入断点,我击中了应用程序初始化方法,但它从未击中初始化器中的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);
}
}
}
全球。应用程序初始化方法
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);
}
终于找到了!
在寻找解决方案时,我遇到了这个帖子实体框架数据库。SetInitializer不工作
应用那里建议的解决方案来强制我的数据库创建在启动时像我预期的那样工作,但是在运行种子代码时,它抛出了一个空指针异常。在调查过程中,我意识到任何从Context类引用DBSet集合的尝试都会产生相同的异常。进一步检查后,我发现不用
public DbSet<MobileTerminal> MobileTerminals { get; set; }
我用了
public DbSet<MobileTerminal> MobileTerminals;
这意味着我没有得到任何隐式的对象初始化,因此空指针异常。我删除了强制初始化代码并再次运行应用程序,这一次种子代码没有运行,直到我访问了一个实际查询数据上下文的页面,它运行得很好。显然,由于延迟加载,初始化代码直到实际需要时才运行,即第一次在应用程序中查询数据上下文。
我希望这对将来有同样问题的人有所帮助。
我想分享另一个问题,当使用类库的代码首先&偶然发现了这篇文章。我在一个库项目中也有我的代码第一个POCO和DataContext类,并想使用这个项目来创建我的代码第一个数据库。我发现有一个-ProjectName标志,可以指定创建数据库时要查找的类库项目。
add-migration -Name 'InitialCreate' -ProjectName 'MyProject.Data'
update-database -ProjectName 'MyProject.Data'
问题可能与您在web.config中使用的connectionstring有关。
对于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初始化数据库。配置,而不是从全局。asax文件