【问题标题】:Entity Framework Code First in class library类库中的实体框架代码优先
【发布时间】:2011-12-25 19:11:19
【问题描述】:

我今天早上刚开始尝试 EF4 代码,我在一个单独的类库中创建了我的 POCO、数据上下文和 Initializer 类,我相信这是常规的样板类型代码。我在 MVC3 应用程序中引用该类并在 Global.asax 中设置初始化程序。在运行应用程序时,我注意到以下问题
1. 没有在任何地方创建数据库(然后我在 web.config 中为一个以 Context 类命名的连接字符串添加了一个条目,仍然没有结果)
2.当我尝试访问初始化的值时,我得到一个空错误,显然是因为没有数据。

谁能帮我指点一下如何让这个东西工作(如果我整个圣诞节都在学习这个,但我仍然无法让它工作,那将是一种耻辱:() 谢谢
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);
        }
    }
}

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);
    }

【问题讨论】:

  • 发布初始化类怎么样?或者至少是上下文类。

标签: c# .net entity-framework-4 entity-framework-4.1


【解决方案1】:

尤里卡..终于!
在寻找解决方案时,我遇到了这个帖子Entity Framework Database.SetInitializer simply not working
应用那里建议的解决方案来强制我的数据库在启动时像我预期的那样创建工作,但是在运行种子代码时,它抛出了一个空指针异常。在调查过程中,我意识到任何从 Context 类引用 DBSet 集合的尝试都会产生相同的异常。进一步检查我意识到,而不是使用

 public DbSet<MobileTerminal> MobileTerminals { get; set; }

我用过

   public DbSet<MobileTerminal> MobileTerminals;

这意味着我没有得到任何隐式对象初始化,因此出现了空指针异常。我删除了强制初始化代码并再次运行应用程序,这一次种子代码没有运行,直到我访问一个实际查询数据上下文的页面并且它运行完美。
显然,由于延迟加载,初始化代码直到实际需要时才运行,即第一次在应用程序中查询数据上下文。

我希望这对以后遇到同样问题的人有所帮助。

【讨论】:

  • 有点离题,但调试的一个有趣的方法是使用上面的代码和DropCreateDatabaseIfModelChanges 而不是DropCreateDatabaseAlwaysface-palm 时刻)。如果您为这个问题来到此页面并且上述解决方案不起作用,请检查您是否没有这样做。一个快速的解决方法是将其更改为DropCreateDatabaseAlways,或者只是将一个虚拟属性添加到您的模型/删除虚拟属性。
【解决方案2】:

我想分享另一个问题,当我首先使用类库编写代码时偶然发现了这篇文章。我在一个库项目中也有我的代码优先 POCO 和 DataContext 类,并且想使用这个项目来创建我的代码优先数据库。我发现有一个 -ProjectName 标志,可以在创建数据库时指定要查找的类库项目。

   add-migration -Name 'InitialCreate' -ProjectName 'MyProject.Data'

   update-database -ProjectName 'MyProject.Data'  

【讨论】:

  • 在包管理器控制台 get-help enable-migrations -detailedget-help add-migration -detail 中查看其他有用的标志,用于 DBContext 和实体在类库中但连接字符串在另一个项目中的情况
【解决方案3】:

问题可能与您在 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 文件初始化数据库

【讨论】:

  • 您好,感谢您的回复。我已经这样做了,但仍然没有爱。我尝试检查 Application_Start 方法中使用的连接字符串及其没有设置初始目录的 SQl Express 连接字符串。尽管事实上我已经在 web.config 和类库的 app.config 文件中设置了连接字符串。你怎么认为?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 1970-01-01
  • 2012-02-12
相关资源
最近更新 更多