简体   繁体   中英

Accessing Entity Framework In Class Library From ASP.NET Core Web App

I currently have 2 projects in my solution, an ASP.NET Core Web Application and a .NET 4.6.1 (non-core) class library. In my class library, I have added Entity Framework 6 and, using Database First generation, created all my db context classes. Inside the class library, everything is working as expected; however, when I try to access the ef classes from the .NET Core Web App, it doesn't have a connection string to use and fails.

Now, in the old ways, I know that I could copy the connection string settings from the app.config in my class library to the web.config in the web application, but .NET Core doesn't support this.

I've tried using the steps outlined here , but that only works for Code-First db generation (which I am not doing). I also looked into switching to using EntityFrameworkCore, but I can't get the db-first generation to happen (using this overview ).

Is there any way to achieve what I am trying to do?

Below is how you can provide the entire configuration in the codebase for EF models and how to provide the connection strings at runtime. I recently struggled with this too because documentation on this is a little hard to find.

Let's assume you generated your model from your database (DB-First): MyEntities.edmx

You will have a partial class in your project such as this:

public partial class MyEntities : DbContext
{
    public MyEntities ()
        : base("name=MyEntities")
    {
    }

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

    public virtual DbSet<MyTable> MyTable { get; set; }
}

When you generated your model in VS, if you selected to store the connection string in the config file the automatic code generation will put the connection string config name in the constructor as it is above: public MyEntities(): base("name=MyEntities")

And in the config of your project you will have something like:

<configuration> <connectionStrings> <add name="MyEntities" connectionString="metadata=res://MyProject/MyEntities.csdl|res://MyProject/MyEntities.ssdl|res://MyProject/MyExchangeEntities.msl;provider=System.Data.SqlClient;provider connection string='data source=SERVERADDRESS;initial catalog=DATABASENAME;persist security info=True;user id=USERID;password=PASSWORD;MultipleActiveResultSets=True;App=EntityFramework'" /> </connectionStrings> </configuration>

Now to bypass this, if you take a look at the DbContext constructor: public DbContext(string nameOrConnectionString); it actually says you can pass the connection string directly to it.

So all that you need to do is to extend this partial class and add another constructor that takes a connectionstring.

public partial class MyEntities
{
    /// <summary>
    /// This constructor allows us to pass connection strings at runtime
    /// </summary>
    /// <param name="connectionString">Entity Framework connection string</param>
    public MyEntities(string connectionString) : base(connectionString)
    {

    }
}

Even though it is obvious, I just want to mention that we extend the partial class instead of modifying the auto generated one so it doesn't get overwritten when we re-generate the model in the future.

To connect using your connection string you simply construct your object like this: new MyEntities("metadata=res://MyProject/MyEntities.csdl|res://MyProject/MyEntities.ssdl|res://MyProject/MyExchangeEntities.msl;provider=System.Data.SqlClient;provider connection string='data source=SERVERADDRESS;initial catalog=DATABASENAME;persist security info=True;user id=USERID;password=PASSWORD;MultipleActiveResultSets=True;App=EntityFramework'");

And finally, if you want to provide the EF configuration in the codebase as well, it can be done like this:

/// DbConfiguration belongs to System.Data
public class EntityFrameworkConfig : DbConfiguration
{
    public EntityFrameworkConfig()
    {
        //We set configurations for entity framework here so that we don't have to add it in the app.config
        this.SetDefaultConnectionFactory(new SqlConnectionFactory());
        this.SetProviderServices(SqlProviderServices.ProviderInvariantName, SqlProviderServices.Instance);
    }
}

/// <summary>
/// This class with the DbConfigurationType attribute allows EntityFramework to know    
/// to get its config from the EntityFrameworkConfig class instead of the app.config
/// </summary>
[DbConfigurationType(typeof(EntityFrameworkConfig))]
public partial class MyEntities
{
    /// <summary>
    /// This constructor allows us to pass connection strings at runtime
    /// </summary>
    /// <param name="connectionString">Entity Framework connection string</param>
    public MyEntities(string connectionString) : base(connectionString)
    {

    }
}

Long story short: You have to copy your ConnectionString to the web.config/app.config of your hosting project. Your Class Library cant run with out Console Application / MVC / Web API, without one of this applications its just a dll. So to sum it up, you need to copy all Connection Strings and other important to the web.config file of the hosting project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM