Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DbProviderFactories.GetFactoryClasses returns no results after installing .NET SQL Client in .NET Core 2.1

I'm porting a library over to .NET Core 2.1 now that it has support for DbProviderFactory. For the most part it has gone fine - it compiles, but when run I get an error:

System.ArgumentException: 'The specified invariant name 'System.Data.SqlClient' wasn't found in the list of registered .NET Data Providers.'

I've used DbProviderFactories.GetFactoryClasses() to check if there are any providers installed, and there doesn't appear to be (0 rows in the resulting table).

So I guess my question is, how can I install the data providers for .NET Core? I've got .NET Framework 4.5 on the machine and it is picking up the data providers without any issue. I don't want to install System.Data.SqlClient as a Nuget for the local project, since that would add a dependency that would make the DbProviderFactory irrelevent. That said, I have attempted to install System.Data.SqlClient in a project that uses my library as a test, and it still isn't picked up.

like image 890
Allan Jardine Avatar asked Aug 24 '18 15:08

Allan Jardine


3 Answers

In .NET Framework, the providers are automatically available via machine.config and are also registered globally in the GAC. In .NET Core, there is no GAC or global configuration anymore. This means that you'll have to register your provider in your project first, like so:

using System.Collections.Generic;
using System.Data.CData.MySQL; // Add a reference to your provider and use it
using System.Data.Common;
using System.Linq;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // Register the factory
            DbProviderFactories.RegisterFactory("test", MySQLProviderFactory.Instance);

            // Get the provider invariant names
            IEnumerable<string> invariants = DbProviderFactories.GetProviderInvariantNames(); // => 1 result; 'test'

            // Get a factory using that name
            DbProviderFactory factory = DbProviderFactories.GetFactory(invariants.FirstOrDefault());

            // Create a connection and set the connection string
            DbConnection connection = factory.CreateConnection();
            connection.ConnectionString = "Server = test, Database = test";
        }
    }
}

As you can see, I had to add a reference to my Provider, "System.Data.CData.MySQL" in this case.

It's sad that you can't just get all available providers anymore, but this is what we have to work with in .NET core.

(Information from this GitHub corefx issue)

like image 77
Joshua VdM Avatar answered Nov 10 '22 05:11

Joshua VdM


As Amer mentioned before:

In .net core you have to register the Factory

For SQL: DbProviderFactories.RegisterFactory("System.Data.SqlClient", SqlClientFactory.Instance);

However, to do this you should add the System.Data.SqlClient nuget package to your project.

Like this (Tools -> Nuget package manager -> Package Manager Console)

Find-Package SQLClient
Install-Package System.Data.SqlClient -ProjectName YourProjectName
like image 4
Aleksandr Sorokin Avatar answered Nov 10 '22 04:11

Aleksandr Sorokin


In .net core you have to register the Factory

For SQL: DbProviderFactories.RegisterFactory("System.Data.SqlClient", SqlClientFactory.Instance);

like image 1
Amer Jamaeen Avatar answered Nov 10 '22 04:11

Amer Jamaeen