1

I´m new at this, so maybe the problem is quite obvious for you, but for me it has been a time consuming attempt. I am building a parking program in C# and am using Dapper to query a MariaDB database that I manage through Heidi. I am using VS2022, C# v.11, Net 6.0, MariaDB V.1O.11 and Dapper 2.0.

The thing is that when I try to retrieve values from the Database into a class using Dapper´s DynamicParameters, it just returns null. I can save objects into the Database, but not retrieve them, so I guess the problem is either in my Query, or my Stored Procedure, since the connection is succesful.

The StoredProcedure receives a string ("folio") that acts like an ID and should return two values (columns) from the table ("estatus" which is a string and "horaEntrada" which is a DateTime), that have a coincidence with "folio". In other words, should look for a coincidence with "folio" in column "Folio" and return the values that are under "Estatus" and "HoraEntrada" columns and assign those values to "estatus" and "horaEntrada" respectively.

This is my code (removed all code that had nothing to do with my question). In here, I use a model named "PorHoraModel" and a stored procedure called "spPorHoraFolio_Get". Variable "builder" is my connection string

public static PorHoraModel GetFolio(PorHoraModel modelo)
        {
            var builder = MariaDBConnector();
            using (var connection = new MySqlConnection(builder))
            {
                connection.Open();

                var p = new DynamicParameters();
                p.Add("@folio", modelo.Folio, DbType.String, ParameterDirection.Input);
                p.Add("@estatus", modelo.Status, DbType.String, ParameterDirection.Output);
                p.Add("@horaEntrada", modelo.HoraEntrada, DbType.DateTime, ParameterDirection.Output);

                modelo = connection.QueryFirstOrDefault<PorHoraModel>("spPorHoraFolio_Get", p, commandType: CommandType.StoredProcedure);

                connection.Close();

                return modelo;
            }
        }

And this is my Stored Procedure ("spPorHoraFolio_Get"), that uses "listadoporhora" database to get the values from "Folio" column (search parameter), "Estatus" column (output paramenter) and "HoraEntrada" column (output parameter)

CREATE DEFINER=`root`@`localhost` PROCEDURE `spPorHoraFolio_Get`(
    IN `folio` VARCHAR(14),
    OUT `estatus` VARCHAR(5),
    OUT `horaEntrada` DATETIME
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN

SELECT Folio, Estatus, HoraEntrada 
FROM listadoporhora
WHERE (Folio = folio);

END

Thanks in advance for your help!

vmroche
  • 11
  • 3
  • It looks like MariaDB as of version 10.6 and on, is not fully compatible with C#, due to a character set 'utf8mb3' not being supported by the NET Framework. I have found this article about it: https://jira.mariadb.org/browse/MDEV-26105 Should someone have a different information, please let me know..... – vmroche May 04 '23 at 00:01
  • According to that link the problem was resolved by adopting a new .net driver version. I tried copying the details but this is all my phone would capture is this: https://dev.mysql.com/doc/relnotes/connector-net/en/news-8-0-28.html so check the resolution note and make sure you use the version recommended (or later versions probably) – Paul Maxwell May 05 '23 at 02:12
  • Thank you! Obviously I´m doing something wrong, it is just that I can´t figure out what! I did install the latest driver, but the issue continues.... Thank you anyway for your time! – vmroche May 05 '23 at 03:44
  • Perhaps ask a separate question about the Mariadb issue? and another about the combo Mariadb+Heidi? Good Luck. – Paul Maxwell May 05 '23 at 03:52

1 Answers1

0

You are using the QueryFirstOrDefault method that is designed to return a single row. However the stored procedure is not deliberately limited to just 1 row, so try using the Query() method instead as this permits multiple rows. e.g.

public static PorHoraModel GetFolio(PorHoraModel modelo)
{
    var builder = MariaDBConnector();
    using (var connection = new MySqlConnection(builder))
    {
        connection.Open();

        var p = new DynamicParameters();
        p.Add("@folio", modelo.Folio, DbType.String, ParameterDirection.Input);
        p.Add("@estatus", modelo.Status, DbType.String, ParameterDirection.Output);
        p.Add("@horaEntrada", modelo.HoraEntrada, DbType.DateTime, ParameterDirection.Output);

        var results = connection.Query<PorHoraModel>("spPorHoraFolio_Get", p, commandType: CommandType.StoredProcedure);

        if (results.Count > 0)
        {
            modelo = results.First();
        }

        connection.Close();

        return modelo;
    }
}

If you only expect the stored proc to return one row, then you need to revisit that SQL to ensure that is true. If this is done then you can use the QueryFirstOrDefault method.

e.g. If you want to get the most recent data, you could modify the stored procedure to include an ORDER BY clause, sorting the results in descending order based on a date column. For example:

SELECT col1, date_column FROM your_table
ORDER BY date_column DESC
LIMIT 1;

Then, in your C# code, you can use the FirstOrDefault() method instead of First(), which will return the first row (the most recent date) or the default value if the result set is empty:

if (results.Count() > 0)
{
    modelo = results.FirstOrDefault();
}

Try this:

var results = connection.Query<dynamic>("spPorHoraFolio_Get", p, commandType: CommandType.StoredProcedure);

foreach (var row in results)
{
    var fields = row as IDictionary<string, object>;
    var estatus = fields["estatus"];
    var horaEntrada = fields["horaEntrada"];
    // Process the values as needed
}

refer: How to return dynamic values in Dapper

Paul Maxwell
  • 33,002
  • 3
  • 32
  • 51
  • Thank you for your input. I did as you said and I am still getting null values. I´m trying to get a class object "PorHoraModel", but I´m getting an IEnumerable with null values. "results.count > 0" also throws me an error "Operator '>' cannot be applied to operands of type 'method group' and 'int'. – vmroche May 04 '23 at 06:10
  • it should have been `results.Count() > 0` - sorry, plus I added something else that may help – Paul Maxwell May 04 '23 at 07:16
  • I really thank you for your effort trying to help me out! sincerely!. It is still giving me null values. This is what I did: foreach (var row in results) { var fields = row as IDictionary; var estatus = fields["estatus"]; var horaEntrada = fields["horaEntrada"]; modelo.Status = (string)estatus; modelo.HoraEntrada = (DateTime)horaEntrada; }; – vmroche May 04 '23 at 17:29
  • The thing is that when I run this using MS SQL, it works just fine, it is with MariaDB and Heidi that I´m having these issues..... – vmroche May 04 '23 at 17:31
  • As I cannot replicate your exact environment I'm unable to offer much more on this. Sorry. – Paul Maxwell May 05 '23 at 02:16