MySqlConnection.Open() System.InvalidCastException: Object cannot be cast from DBNull to other types
Asked Answered
E

7

8

I have simple connectionstring to MySql (MariaDB 5.5.5-10.11.0) written in c#:

MySqlConnection Database = new MySqlConnection("Server=127.0.0.1; Port=3306; Database=test; Uid=user; Pwd=MyPassword; Ssl Mode=Required; convert zero datetime=True;");

Everything works fine on two computers (Windows 10 and Windows 11). But when I try to launch this app on Windows Server 2022 I get this error:

System.InvalidCastException: Object cannot be cast from DBNull to other types.
   at System.DBNull.System.IConvertible.ToInt32(IFormatProvider provider)
   at System.Convert.ToInt32(Object value, IFormatProvider provider)
   at MySql.Data.MySqlClient.Driver.LoadCharacterSets(MySqlConnection connection)
   at MySql.Data.MySqlClient.Driver.Configure(MySqlConnection connection)
   at MySql.Data.MySqlClient.MySqlConnection.Open()
   at MariaDB.Program.StartAPI()

Error is thrown on Database.Open();

MariaDB is installed and running, Ssl is working, user's pemissions are granted, port is correct. Any ideas please?

Whole program:

using System;
using MySql.Data.MySqlClient;

namespace MariaDB
{
    internal class Program
    {
        MySqlConnection Database = new MySqlConnection("Server=127.0.0.1; Port=3306; Database=test; Uid=user; Pwd=MyPassword; Ssl Mode=Required; convert zero datetime=True;");

        static void Main(string[] args)
        {
            Program p = new Program();
            p.OpenDB();
        }

        private void OpenDB()
        {
            Database.Open();
            Console.WriteLine("Ok");
            Console.ReadLine();
        }
    }
}
Exerciser answered 13/10, 2022 at 18:32 Comment(10)
You did not show any code with a line of Database.Open(); . Opening a database connection is not a cast and does not involve other types so your error is very, very likely elsewhereHeadon
I did a little decompilation and found that LoadCharacterSets is being called when the connection is opened the first time. It's execting SHOW COLLATION and reading the record set. Apparently,. it's getting a NULL for the id column,, and Convert.Int32 is throwing because of that. If you execute that statement in a query tool, what do you get (please edit the question and add the record set)?Gridley
That said, consider switching to MySqlConnector. It's a better library for MySQL/MariaDB in general.Gridley
ŇɏssaPøngjǣrdenlarp check it now. Hope that now you can helpExerciser
Do not try to re-use the same connection throughout the program. ADO.Net already does connection pooling for you, and this interferes with it in a way that makes things slower.Mettle
madreflection after running SHOW COLLATION I got huge table so here is link to google drive, it is in excel: link. There are really null values. Don't know why because on my PC there are no null values.Exerciser
So, this is interesting. This doesn't appear to be a misconfiguration. But even the latest MySql.Data package still does this query without checking for NULL, so I don't know why they would have done that. MySqlConnector doesn't do this as far as I can tell. Try it out.Gridley
So I updated to MySqlConnectionStringBuilder but still the same result. Everything ok on my PC but same error message on Win Server.Exerciser
"updated to MySqlConnectionStringBuilder" - That's not at all what was suggested. You're still using the MySql.Data package.Gridley
So I removed MySql.Data.MySqlClient and added MySqlConnector. Now it finally works everywhere even without MySqlConnectionStringBuilder. So it is enough to just change the libraries. Thank you a lot. I will change the code in question to old one and you can write changing libraries as the answer. Then i will mark it as correct one. Thank you again, it really helped me a lot.Exerciser
D
20

The same thing happened to me. Change MySql.Data.MySqlClient to MySqlConnector and the problem was solved

The database I use is already in production so it was easier for me to change the connector instead of downgrading my database

I detail a little what I did:

  • My project was working on Visual Studio 2017 with .NET Core 2.1. I had to update to Visual Studio 2022 and change the .NET Core to version 3.1
  • In NuGet package manager uninstall MySql.Data and install MySqlConnector version 2.2.2
  • Follow the recommendations of the official page MySqlConnector
Demography answered 9/12, 2022 at 0:0 Comment(2)
Can you elaborate a little bit on what all needs to be switched over going from mysqlclient to mysqlconnector?Modish
Even if MySqlConnector is preferable (better performance and defaults), PR pushed (github.com/mysql/mysql-connector-net/pull/51) to correct that. Using CharacterSet=utf8mb4 with 10.10.1+ is a must-have even if accepted until jira.mariadb.org/browse/MDEV-30164 is released.Saskatchewan
Z
11

This is caused by MariaDB 10.10.1 making ID field Nullable in Information_Schema.Collations and adding a bunch of Collations that have null for an ID.

https://jira.mariadb.org/browse/MDEV-27009

One possible workaround is to use MariaDB 10.9 or older.

Zymogenesis answered 3/12, 2022 at 22:12 Comment(1)
Reading through the jira link, MySqlConnector seems to be the recommended resolution.Amadou
D
3

I tried latest RC as well and it seems MariaDB will have this problem forever or atleast current MySql.Data.MySqlClient have a problem with it.

The suggested answer is either rolling back to 10.9 or using a totally different connector like MysqlConnector.

To switch to MysqlConnector, simply install that in your project via NuGet or if you want to build it yourself download it from Git.

Then in your app.config or web.config add the new dataProvider so .net knows about it. ex, in app.config/web.config add:

<configuration><system.data><DbProviderFactories>
<remove invariant="MySqlConnector"/>
      <add name="MySqlConnector" invariant="MySqlConnector" description="Async MySQL ADO.NET Connector" type="MySqlConnector.MySqlConnectorFactory, MySqlConnector, Culture=neutral" />
</DbProviderFactories>

then use it in your connectionStrings make sure you use dataProvider="MysqlConnector"

Special thanx to Ville & Miguel McFly!

Doeskin answered 16/12, 2022 at 10:14 Comment(0)
C
2

Here is how the MySql.Data load collations: enter image description here

This method assume that the "id" column's value is not null. Unfortunately, from the version 10.10, MariaDB switch the "Id" column to "Allow Null" and there are a lot of row in Collations with NULL Id. That causes the "Object cannot be cast from DBNull to other types" exception.

Seem 10.9 is the only option for now if you wish to use the MySql.Data package and wait for a fix in MySql.Data.

Caliban answered 7/12, 2022 at 8:49 Comment(0)
F
1

Suffering from the same issue and Oracle to not merging the related PR, i made a fork & a nuget package to deal with it. Migrating to MysqlConnector is not always a possibility.

Forked package: https://www.nuget.org/packages/MediReport.MySql.Data/8.1.0

Original PR: https://github.com/mysql/mysql-connector-net/pull/51/commits/7a7aeec16807a17e07d55de1ae83b37aa9a960a7

Fidget answered 20/9, 2023 at 10:56 Comment(0)
P
1

MariaDB recently released fix for it https://jira.mariadb.org/browse/MDEV-31608, in 10.11.7 and later.

If you can't use MySqlConnector, you can use latest MariaDB server version. (But if you can use MySqlConnector, it is very much worth trying, it is a better one in terms of quality, and performance)

Pediment answered 20/2 at 7:29 Comment(0)
P
0

If you can't migrate to MySqlConnector try this and let me know if it helped. Just published pre-pre-alpha version of package trying to fix this issue.

NuGet: https://www.nuget.org/packages/Jf.MySql.Data.Collations/

Sources: https://github.com/jeffraska/Jf.MySql.Data.Collations/

The package is in "works on my computer" state. This means .NET framework 4.5, really old MySql.Data 6.9.7 library and latest MariaDB 10.11.4 currently available in Debian repository. So don't expect miracles.

It uses standard Command Interceptor functionality of MySql.Data library (https://dev.mysql.com/doc/connector-net/en/connector-net-interceptors.html) to alter all SHOW COLLATION queries and replacing it with SHOW COLLATION WHERE id IS NOT NULL.

Also the package have functionality to alter MySql.Data's internal charset mapping to allow reading utf8mb3 fields in pre 8.0.28 versions of MySql.Data .

Pestilence answered 11/12, 2023 at 5:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.