在Entity Framework 6中创建第一个DbContext创建模型

时间:2016-09-13 07:22:38

标签: entity-framework asp.net-core asp.net-core-mvc ef-model-first

在我的web项目中,我尝试使用Entity Framework 6模型的第一种方法。模型是从单独项目中的现有数据库生成的。对于模型生成,连接字符串保存在数据访问项目的app.config中。在主Web项目(ASP.NET Core MVC)中 我试图在Startup.cs类中注入上下文创建。

下面是上下文部分类的代码。使用部分类是因为上下文是从模板自动生成的。

[DbConfigurationType(typeof(EntityFrameworkConfig))]
public partial class MyEntities
{
    public MyEntities(String name) : base(name)
    {    
    }
}

为了从代码中使用实体框架配置而不是用于asp.net核心项目的app.config,我有从System.Data.Entity.DbConfiguration继承的配置类

public class EntityFrameworkConfig : DbConfiguration
{
    public EntityFrameworkConfig()
    {
         this.SetDefaultConnectionFactory(new SqlConnectionFactory());
         this.SetProviderServices(SqlProviderServices.ProviderInvariantName,       SqlProviderServices.Instance);
    }
}

在web项目的config.json中,我有连接字符串:

{
    "MailSettings": {
    "ToAddress": "foo@bar.com"
    },
    "Connection": {
    "ConnectionString": "data source=SERVER;initial catalog=DB;user id=user;password=pwd;MultipleActiveResultSets=True;App=EntityFramework;"
    }
}

在Startup.cs中:

public void ConfigureServices(IServiceCollection services)
{
    ...

    String connStr = _config["Connection:ConnectionString"];
    services.AddScoped((_) => new MyEntities(connStr));
    ...

}

我遇到从自动生成的上下文类的OnModelCreating事件抛出的UnintentionalCodeFirstException:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    throw new UnintentionalCodeFirstException();
}

这是使用实体框架6模型第一种方法与asp.net Core MVC项目的正确方法吗?这个例外的原因是什么?

2 个答案:

答案 0 :(得分:2)

这些是您在使用ASP.net Core和EF 6时应遵循的步骤。这只是一个示例。您必须根据您的使用情况进行更改。

第1步: project.json

为完整的.NET Framework指定单个目标:

"frameworks": {
    "net46": {}
}

第2步:设置连接字符串和依赖项注入

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(string nameOrConnectionString) : base(nameOrConnectionString)
    {
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped((_) => new ApplicationDbContext(Configuration["Data:DefaultConnection:ConnectionString"]));

    // Configure remaining services
}

第3步:将配置从配置迁移到代码

实体框架6允许在xml(在web.config或app.config中)或通过代码指定配置。从ASP.NET Core开始,所有配置都是基于代码的。

<entityFramework>
    <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>

然后:

[DbConfigurationType(typeof(CodeConfig))] // point to the class that inherit from DbConfiguration
public class ApplicationDbContext : DbContext
{
    [...]
}

public class CodeConfig : DbConfiguration
{
    public CodeConfig()
    {
        SetProviderServices("System.Data.SqlClient",
            System.Data.Entity.SqlServer.SqlProviderServices.Instance);
    }
}

参考: ASP.NET Core and Entity Framework 6

答案 1 :(得分:0)

挖掘后我发现解决方案是以实体框架格式提供连接字符串,使DbContext类能够加载模型元数据。
 在Startup.cs中:

String connStr = _config["Connection:ConnectionString"];
String efConnString = BuildConnectionString(connStr);
services.AddScoped((_) => new MyEntities(efConnString));  
....  
....
private String BuildConnectionString(String cs)
{
    EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
    entityBuilder.Provider = "System.Data.SqlClient";
    entityBuilder.ProviderConnectionString = cs;
    entityBuilder.Metadata = @"res://*/XXXWebModel.csdl|
                        res://*/XXXWebModel.ssdl|
                        res://*/XXXWebModel.msl";
    return entityBuilder.ToString();
}

当连接字符串以不包含元数据信息的格式提供时,在哪里查找生成的模型实体框架会发现使用代码第一种方法,这就是调用抛出异常的方法OnModelCreating的原因:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    throw new UnintentionalCodeFirstException();
}  

发送形成为包含元数据信息的实体框架连接字符串的连接字符串解决了问题。