Closed toschug closed 6 years ago
Make sure you have a reference added to System.Data.SqlClient? It should be there if you're using this library but if you use your own code you have to make sure you add the dependency to your project.
I am aware of this, but thanks for pointing this out.
I even added System.Data.SqlClient
explicit although it gets already referenced by WestWind.Utilities.
Same exception.
What I am trying to say is that when I pass the string parameter "System.Data.SqlClient"
to DataUtils.GetDbProviderFactory
then it will run straight into the NotSupportedException
.
First, the value of providerName
(with uppercase N in name) gets converted to lower case and assigned to providername
(wither lowercase n in name). Later on the uppercase variant (providerName
) gets checked against the lowercase hardcoded strings (like "system.data.sqlclient"
). So it can never evaluate to true and thus falls through to the Exception. The only time when it should work is against MySql.Data
/mysql.data
.
I hope it explains it better what I mean, sorry for confusion.
Excerpt from master branch (https://raw.githubusercontent.com/RickStrahl/Westwind.Utilities/master/Westwind.Utilities/Utilities/DataUtils.cs) with some comments (UPPERCASE
/ LOWERCASE
):
// UPPERCASE
public static DbProviderFactory GetDbProviderFactory(string providerName)
{
#if NETFULL
return DbProviderFactories.GetFactory(providerName);
#else
// LOWERCASE
var providername = providerName.ToLower();
// UPPERCASE <-> LOWERCASE -> always false
if (providerName == "system.data.sqlclient")
return GetDbProviderFactory(DataAccessProviderTypes.SqlServer);
if (providerName == "system.data.sqlite" || providerName == "microsoft.data.sqlite")
return GetDbProviderFactory(DataAccessProviderTypes.SqLite);
// LOWERCASE<->LOWERCASE -> true!
if (providerName == "mysql.data.mysqlclient" || providername == "mysql.data")
return GetDbProviderFactory(DataAccessProviderTypes.MySql);
if (providerName == "npgsql")
return GetDbProviderFactory(DataAccessProviderTypes.PostgreSql);
throw new NotSupportedException(string.Format(Resources.UnsupportedProviderFactory,providerName));
#endif
}
I ran into this same problem just a moment ago, looked at the source and noticed the same issue. I was about to write up a ticket and it looks like @toschug beat me by a couple days. You're converting the providerName
to lower case as providername
and then using the unconverted providerName
parameter passed to the method to compare against your lower case strings in most of the conditions.
I'd recommend using the string Equals with the IgnoreCase option rather than converting your string, as well.
public static DbProviderFactory GetDbProviderFactory(string providerName)
{
#if NETFULL
return DbProviderFactories.GetFactory(providerName);
#else
if (providerName.Equals("system.data.sqlclient", StringComparison.OrdinalIgnoreCase))
return GetDbProviderFactory(DataAccessProviderTypes.SqlServer);
if (providerName.Equals("system.data.sqlite", StringComparison.OrdinalIgnoreCase) ||
providerName.Equals("microsoft.data.sqlite", StringComparison.OrdinalIgnoreCase))
return GetDbProviderFactory(DataAccessProviderTypes.SqLite);
if (providerName.Equals("mysql.data.mysqlclient", StringComparison.OrdinalIgnoreCase) ||
providerName.Equals("mysql.data", StringComparison.OrdinalIgnoreCase))
return GetDbProviderFactory(DataAccessProviderTypes.MySql);
if (providerName.Equals("npgsql", StringComparison.OrdinalIgnoreCase))
return GetDbProviderFactory(DataAccessProviderTypes.PostgreSql);
throw new NotSupportedException(string.Format(Resources.UnsupportedProviderFactory,providerName));
#endif
}
Thanks for the catch on this... I made the fix comparing to the proper string. Duh :-)
I avoided individual Equals calls because there are a lot of them to avoid overhead of many comparisons. Probably negligible but old habits and all...
Your blog post about
DbProviderFactory
brought me here as I am trying to get a lib to .NET Standard. After some (unsuccesful) testing: Is it possible, that there is some kind of variable "mismatch" inDataUtils.GetDbProviderFactory
regardingprovidername
andproviderName
?The exception I get is:
System.NotSupportedException: 'Unsupported Provider Factory specified: System.Data.SqlClient'
I replaced
providername
/providerName
with_lower
to make it clearer what I mean:For now I ripped off this bit into "my" lib for a first workaround (and to see that it could be that mismatch):
I hope it is some help and that I don't misunderstand something completly. Thanks anyway (and for the blog post ;) )