Using a EF Repository with custom connection objec

2019-04-10 06:19发布

I am stuck in EF 6 and the documentation is sparse - not getting that solved for a day now.

I try to use Code First on a database repository we have. Due to complex initialization I must use my own factory method to initialize the context subclass and I must put my own sql connection in, or make my own factory.

THe following class initialization:

we have:

public class Repository : DbContext {

static string _connectionString;

    static Repository() {
        Database.SetInitializer<Repository>(null);
        var type = typeof(System.Data.Entity.SqlServer.SqlProviderServices);
        _connectionString = ** method to get connection string**
    }

    public static Repository Create() {
        SqlConnection connection = new SqlConnection(_connectionString);
        connection.Open();
        connection.BeginTransaction(IsolationLevel.ReadCommitted).Commit();
        return new Repository(connection);
    }

Sadly running it blows with the following exception on the first attempt to select some entity:

Unable to determine the provider name for provider factory of type 'System.Data.SqlClient.SqlClientFactory'. Make sure that the ADO.NET provider is installed or registered in the application config.

I am totally out of my mind how to fix that.

My config file in the using web application reads:

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer, Version=6.0.0.0" />
    </providers>   
</entityFramework>

Anyone can tell me how to fix that? My alternative is to move back to model first - but I would really like to give code first a try here.

1条回答
Luminary・发光体
2楼-- · 2019-04-10 06:50

I had the same requirements for my projects: EF repositories had to accept connection instances created from my own factory. To that end I chose to completely ignore the EF config file scheme. Instead, I did the following:

public class Repository : DbContext
{
    static Repository ()
    {
        Database.SetInitializer<Repository>(null);
    }

    public Repository(SqlConnection existingConnection, bool contextOwnsConnection)
        : base(existingConnection, contextOwnsConnection)
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // creating the model myself
    }
    // (...)
}

Since it can accept connection instances from the outside I'm free to use whatever connection factory I want and completely ignore EF's config file scheme.

If you want your connection factory inside the repository (which I don't recommend for the sake of separating concerns), you could add the following to the above:

public Repository()
    : base(CreateConnection(), true)
{
}

private static SqlConnection CreateConnection()
{
    // do whatever you have to do to create your SqlConnection instance, using your own rules
}
查看更多
登录 后发表回答