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

Model first DbContext creation in Entity Framework 6

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

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

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

为了使用代码中的 entity framework 配置而不是 app.config 不能与 asp.net 核心项目一起使用 我有配置 class 继承自 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 class:

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

这是将 Entity framework 6 模型优先方法与 asp.net 核心 MVC 项目一起使用的正确方法吗?出现此异常的原因是什么?

这些是您在使用 ASP.net Core 和 EF 6.This 时应遵循的步骤,只是 example.You 必须根据您的用例进行更改.

第 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: 将配置从配置迁移到代码

Entity Framework 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

在挖掘之后,我发现解决方案是提供 entity framework 格式的连接字符串,使 DbContext class 能够加载模型元数据。
在 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();
}

当以不包含元数据信息的格式提供连接字符串时,在何处查找生成的模型 entity framework 发现使用了代码优先方法,这就是调用方法 OnModelCreating 并抛出异常的原因:

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

发送格式为 entity framework 包含元数据信息的连接字符串的连接字符串解决了问题。