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

4

12

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.

Hypha answered 24/8, 2018 at 15:45 Comment(3)
See following : github.com/dotnet/core/issues/1699Bos
Can you give more info? How did you install the provider for .net? Did you include the dll in your solution and referenced it, did you install it globally for your machine,...Gastrolith
@JoshuaVdM - That's kind of my point. I didn't explicitly install anything. With .NET Framework it just picks the data providers that are available up automatically. I don't know how to install them for .NET Core. Even if I install the SqlClient Nuget for .NET Core I get the same error.Hypha
G
20

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)

Gastrolith answered 27/8, 2018 at 12:50 Comment(2)
Registering this on the Asp.Net Core layer gets rid of this error, however now I'm getting this error. No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlClient'. Make sure the provider is registered in the 'entityFramework' section of the application config fileCogwheel
@Cogwheel With later versions of Entity Framework (6, if I recall correctly), the connection and provider were separated. The provider is now configured independently of the connection strings, in the entityFramework section.Soever
P
5

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
Passover answered 27/8, 2019 at 9:31 Comment(1)
Thank you!!!!!! And all I needed was that one line of code not everything listed by Joshua VdMCofferdam
S
2

In .net core you have to register the Factory

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

Subscription answered 2/7, 2019 at 14:30 Comment(0)
V
1

I also had this issue, but I solved it by this approach:

  1. Firstly you need to register each factory:

    DbProviderFactories.RegisterFactory("System.Data.Obdc","System.Data.Odbc.OdbcFactory, System.Data.Odbc");

  2. DbProvider.FullTypeName will be automatically a string what you inserted into first parameter of RegisterFactoryMethod. (In this case System.Data.Odbc)

Vulcanize answered 1/8, 2023 at 13:51 Comment(1)
It works! but there is a typo, it should be: DbProviderFactories.RegisterFactory("System.Data.*Odbc*","System.Data.Odbc.OdbcFactory, System.Data.Odbc");Cacography

© 2022 - 2024 — McMap. All rights reserved.