implicit cast from object to Int64 fails in ASP.NET app

Posts   
1  /  2
 
    
kbelange
User
Posts: 40
Joined: 07-Dec-2006
# Posted on: 15-Dec-2006 01:32:53   

Here the data type enumeration from the CoreLab docs - dunno why they don't mention the signed/unsigned thing - you should get them to make it explicit!

ms-help: //CoreLab.MySql/MySqlDirect/CoreLab.MySql~CoreLab.MySql.MySqlType.html

MySqlType EnumerationSpecifies the data type of a field or MySqlParameter.

Members Member Description **BigInt A MySQL BIGINT data type that contains a 64-bit signed integer. Represented as the Int64. ** Blob A MySQL BLOB data type that contains a variable-length stream of binary data. Represented as the array of Byte. Char A CHAR data type that contains a fixed-length character string. Represented as the String. Date A MySQL DATE data type that contains a fixed-length representation of a date value. Represented as the DateTime. DateTime A MySQL DATETIME data type that contains a fixed-length representation of a date and time value. Represented as the DateTime. Decimal A MySQL DECIMAL data type that contains values ranging from 1.0 x 10(-28 ) to approximately 7.9 x 10(28 ) with 28-29 significant digits. Represented as the Decimal. Double A MySQL DOUBLE data type. Represented as the Double. Float A MySQL FLOAT data type. Represented as the Float. **Int A MySQL INT data type that contains a 32-bit signed integer. Represented as the Int32. ** SmallInt A MySQL SMALLINT data type that contains a 16-bit signed integer. Represented as the Int16. Text A MySQL TEXT data type that contains a variable-length character string. Represented as the String. Time A MySQL TIME data type that contains a fixed-length representation of a time value. Represented as the TimeSpan. TimeStamp A MySQL TIMESTAMP data type that contains date and time, including seconds. Represented as the DateTime. TinyInt A MySQL UNSIGNED TINYINT data type that contains a 8-bit unsigned integer. Represented as the Byte. VarChar A MySQL VARCHAR data type that contains a variable-length character string. Represented as the String. Year A MySQL YEAR data type that contains a year value. Represented as the Int16. Bit A MySQL BIT data type that contains a bit mask. Represented as the Int64.

Remarks This table shows mappings between MySqlType values, MySQL data types, Microsoft .NET Framework types.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 15-Dec-2006 08:30:48   

Well, this table is definitely not complete. Their docs may say that an int maps onto an int32, it does, but only a signed int. An unsigned int type in a mysql db will be returned as an int64. An unsigned smallint as an int32, an unsigned tinyint as a byte and a signed tinyint as an int16. simple_smile

Today, I'll install 3.55 on another machine and see if I can repro what you're experiencing with that build: that they dropped the signed support or don't use different types for signed types anymore.

Frans Bouma | Lead developer LLBLGen Pro
kbelange
User
Posts: 40
Joined: 07-Dec-2006
# Posted on: 15-Dec-2006 08:38:14   

Something tells me all this badness would go away if we were using MySQL 5, i wouldn't be surprised if this is a legacy MySQL v. 4.1 issue

Otis wrote:

Well, this table is definitely not complete. Their docs may say that an int maps onto an int32, it does, but only a signed int. An unsigned int type in a mysql db will be returned as an int64. An unsigned smallint as an int32, an unsigned tinyint as a byte and a signed tinyint as an int16. simple_smile

Today, I'll install 3.55 on another machine and see if I can repro what you're experiencing with that build: that they dropped the signed support or don't use different types for signed types anymore.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 15-Dec-2006 09:57:40   

Just to rule out any miscommunication: could you please paste me the DDL of the table this Tid field is in so I have a 100% the same testcase here and we're talking about the exact same thing? (and if you could, please post the code you use to fetch the entity).

About 4.1 -> 5.0, I don't think it's related to that, I also tested this on 4.1, as you used that too, so I don't think it will make a difference. It's pure a way of how a 32bit unsigned value will be mapped onto a .net type: you can't map an unsigned 32bit int onto a normal int32 type in .net, so corelab choose to use an int64, which is understandable, as uint is not cls compliant.

(edit): the screenshot you posted shows that the Tid is indeed unsigned, so you should get back an int64. I'll check out what the 3.5x provider does with that kind of fields, though it would surprise me if that would be an int32, simply because I know for a fact people are using 3.5x with llblgen pro and int fields and it works ok, and I can't imagine corelab has now decided to drop the int64, but on the other hand, nothing is impossible with these guys so I'll try to repro it on another box, with 3.55 installed connecting to mysql 4.1x

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 15-Dec-2006 14:55:44   

Ok, on my test system, I execute the following code using Corelab 3.55.17.0, the very latest build, on mysql 4.1.7-nt.

The table: (among other fields, but these two have a role in the testcode, the rest is null) FByte: Tinyint unsigned, PK FInt: Integer unsigned

Ok, the code:

TypetesttableEntity toInsert = new TypetesttableEntity();
toInsert.Fbyte = 1;
toInsert.Fint = (long)10;

TypetesttableEntity loaded= null;
using(DataAccessAdapter adapter = new DataAccessAdapter())
{
    adapter.SaveEntity(toInsert, true);
    loaded = new TypetesttableEntity(1);
    adapter.FetchEntity(loaded);
}
Debug.Assert(typeof(long) == loaded.Fields[(int)TypetesttableFieldIndex.Fint].CurrentValue.GetType());
long value = loaded.Fint.Value;
Console.WriteLine("value: {0}", value);

Works ok and displays '10'

i.o.w: I can't reproduce what you're experiencing. Next I've tried with another entity, Testtable, which has 2 fields: Id, which unsigned integer, PK and identity, and Description, a varchar field:


// continues below the code above
TesttableEntity tte = new TesttableEntity();
tte.Description = "Test";
TesttableEntity tteLoaded = null;
using(DataAccessAdapter adapter = new DataAccessAdapter())
{
    adapter.SaveEntity(tte, true);
    tteLoaded = new TesttableEntity(tte.Id);
    adapter.FetchEntity(tteLoaded);
    adapter.DeleteEntity(tte);
}

Debug.Assert(typeof(long) == tteLoaded.Fields[(int)TesttableFieldIndex.Id].CurrentValue.GetType());
value = tteLoaded.Id;
Console.WriteLine("value: {0}", value);

Again works ok, displays the proper PK value.

i.o.w: it works here... this with the latest official runtime libs of 6-dec-2006

Frans Bouma | Lead developer LLBLGen Pro
kbelange
User
Posts: 40
Joined: 07-Dec-2006
# Posted on: 15-Dec-2006 20:02:45   

I'm not sure what you mean by the DDL, so i'll attach the entity class & the db specific entity type mapping class. I'll also see where the entity gets fetched and post that, but don't laugh - it's not my code and it's pretty ugly (they have an if statement with 7 almost identical cases - one for each day of the week, total cut & paste)

Otis wrote:

Just to rule out any miscommunication: could you please paste me the DDL of the table this Tid field is in so I have a 100% the same testcase here and we're talking about the exact same thing? (and if you could, please post the code you use to fetch the entity).

About 4.1 -> 5.0, I don't think it's related to that, I also tested this on 4.1, as you used that too, so I don't think it will make a difference. It's pure a way of how a 32bit unsigned value will be mapped onto a .net type: you can't map an unsigned 32bit int onto a normal int32 type in .net, so corelab choose to use an int64, which is understandable, as uint is not cls compliant.

(edit): the screenshot you posted shows that the Tid is indeed unsigned, so you should get back an int64. I'll check out what the 3.5x provider does with that kind of fields, though it would surprise me if that would be an int32, simply because I know for a fact people are using 3.5x with llblgen pro and int fields and it works ok, and I can't imagine corelab has now decided to drop the int64, but on the other hand, nothing is impossible with these guys so I'll try to repro it on another box, with 3.55 installed connecting to mysql 4.1x

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 15-Dec-2006 20:46:10   

DDL == Data Definition Language, so the SQL statement to create the table. As you attached a screenshot earlier, of the mysql admin tool with the table def shown, it shows that the field is indeed an int unsigned.

Frans Bouma | Lead developer LLBLGen Pro
kbelange
User
Posts: 40
Joined: 07-Dec-2006
# Posted on: 15-Dec-2006 21:38:07   

CREATE TABLE tutors ( tid int(10) unsigned NOT NULL auto_increment, fname varchar(50) default NULL, mname varchar(50) default NULL, preferredname varchar(100) default '', lname varchar(50) default NULL, gender enum('Male','Female') default NULL, ssn varchar(11) default NULL, dateadded date default '0000-00-00', rating float(4,2) default '-1.00', status enum('Active','Hours Full') default 'Active', notes text, hired tinyint(4) default '-1', datehired date default NULL, isee_exp tinyint(1) default '0', officenotes text, editschedulefirsttime tinyint(4) default '0', sat_exp tinyint(1) default '0', tutor_type enum('Private','NCLB','Both','No Students Currently') default NULL, mugshot longblob, nclb_doc_path varchar(255) default NULL, PRIMARY KEY (tid), KEY lastname (lname) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Otis wrote:

DDL == Data Definition Language, so the SQL statement to create the table. As you attached a screenshot earlier, of the mysql admin tool with the table def shown, it shows that the field is indeed an int unsigned.

kbelange
User
Posts: 40
Joined: 07-Dec-2006
# Posted on: 15-Dec-2006 21:43:26   

I've attached the entity class in a zip file, & here's the Entity fetch & the mapping method from the PersistenceInfoProvider:

    /// <summary>Inits TutorsEntity's mappings</summary>
    private void InitTutorsEntityMappings()
    {
        base.AddElementMapping( "TutorsEntity", "test", @"Default", "tutors", 20 );

** base.AddElementFieldMapping( "TutorsEntity", "Tid", "tid", false, (int)MySqlType.Int, 0, 0, 10, true, "LAST_INSERT_ID()", null, typeof(System.Int64), 0 )**; base.AddElementFieldMapping( "TutorsEntity", "Fname", "fname", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 1 ); base.AddElementFieldMapping( "TutorsEntity", "Mname", "mname", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 2 ); base.AddElementFieldMapping( "TutorsEntity", "Preferredname", "preferredname", true, (int)MySqlType.VarChar, 100, 0, 0, false, "", null, typeof(System.String), 3 ); base.AddElementFieldMapping( "TutorsEntity", "Lname", "lname", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 4 ); base.AddElementFieldMapping( "TutorsEntity", "Gender", "gender", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 5 ); base.AddElementFieldMapping( "TutorsEntity", "Ssn", "ssn", true, (int)MySqlType.VarChar, 11, 0, 0, false, "", null, typeof(System.String), 6 ); base.AddElementFieldMapping( "TutorsEntity", "Dateadded", "dateadded", true, (int)MySqlType.Date, 0, 0, 0, false, "", null, typeof(System.DateTime), 7 ); base.AddElementFieldMapping( "TutorsEntity", "Rating", "rating", true, (int)MySqlType.Float, 0, 0, 0, false, "", null, typeof(System.Single), 8 ); base.AddElementFieldMapping( "TutorsEntity", "Status", "status", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 9 ); base.AddElementFieldMapping( "TutorsEntity", "Notes", "notes", true, (int)MySqlType.Text, 65535, 0, 0, false, "", null, typeof(System.String), 10 ); base.AddElementFieldMapping( "TutorsEntity", "Hired", "hired", true, (int)MySqlType.TinyInt, 0, 0, 4, false, "", null, typeof(System.Int16), 11 ); base.AddElementFieldMapping( "TutorsEntity", "Datehired", "datehired", true, (int)MySqlType.Date, 0, 0, 0, false, "", null, typeof(System.DateTime), 12 ); base.AddElementFieldMapping( "TutorsEntity", "IseeExp", "isee_exp", true, (int)MySqlType.TinyInt, 0, 0, 1, false, "", null, typeof(System.Int16), 13 ); base.AddElementFieldMapping( "TutorsEntity", "Officenotes", "officenotes", true, (int)MySqlType.Text, 65535, 0, 0, false, "", null, typeof(System.String), 14 ); base.AddElementFieldMapping( "TutorsEntity", "Editschedulefirsttime", "editschedulefirsttime", true, (int)MySqlType.TinyInt, 0, 0, 4, false, "", null, typeof(System.Int16), 15 ); base.AddElementFieldMapping( "TutorsEntity", "SatExp", "sat_exp", true, (int)MySqlType.TinyInt, 0, 0, 1, false, "", null, typeof(System.Int16), 16 ); base.AddElementFieldMapping( "TutorsEntity", "TutorType", "tutor_type", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 17 ); base.AddElementFieldMapping( "TutorsEntity", "Mugshot", "mugshot", true, (int)MySqlType.Blob, 2147483647, 0, 0, false, "", null, typeof(System.Byte[]), 18 ); base.AddElementFieldMapping( "TutorsEntity", "NclbDocPath", "nclb_doc_path", true, (int)MySqlType.VarChar, 255, 0, 0, false, "", null, typeof(System.String), 19 ); }

kbelange wrote:

I'm not sure what you mean by the DDL, so i'll attach the entity class & the db specific entity type mapping class. I'll also see where the entity gets fetched and post that, but don't laugh - it's not my code and it's pretty ugly (they have an if statement with 7 almost identical cases - one for each day of the week, total cut & paste)

Otis wrote:

Just to rule out any miscommunication: could you please paste me the DDL of the table this Tid field is in so I have a 100% the same testcase here and we're talking about the exact same thing? (and if you could, please post the code you use to fetch the entity).

About 4.1 -> 5.0, I don't think it's related to that, I also tested this on 4.1, as you used that too, so I don't think it will make a difference. It's pure a way of how a 32bit unsigned value will be mapped onto a .net type: you can't map an unsigned 32bit int onto a normal int32 type in .net, so corelab choose to use an int64, which is understandable, as uint is not cls compliant.

(edit): the screenshot you posted shows that the Tid is indeed unsigned, so you should get back an int64. I'll check out what the 3.5x provider does with that kind of fields, though it would surprise me if that would be an int32, simply because I know for a fact people are using 3.5x with llblgen pro and int fields and it works ok, and I can't imagine corelab has now decided to drop the int64, but on the other hand, nothing is impossible with these guys so I'll try to repro it on another box, with 3.55 installed connecting to mysql 4.1x

kbelange
User
Posts: 40
Joined: 07-Dec-2006
# Posted on: 15-Dec-2006 21:45:18   

I've attached the entity class in a zip file, & here's the Entity fetch & the mapping method from the PersistenceInfoProvider:

Entity fetch:

//get Tutor information TutorApp.EntityClasses.TutorsEntity theTutor = new TutorApp.EntityClasses.TutorsEntity();

            //check to see if this tutor exists
            bool b_tutor = false;
            if(tutid != 0)
            {
                theTutor.Tid = tutid;
                filter = new SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression();
                filter.Add(TutorApp.FactoryClasses.PredicateFactory.CompareValue( TutorApp.TutorsFieldIndex.Tid, SD.LLBLGen.Pro.ORMSupportClasses.ComparisonOperator.Equal,tutid));

                **b_tutor = da.FetchEntityUsingUniqueConstraint(theTutor, filter)**;

                Session["tutorid"] = tutid;
                Session["applicationdone"] = false;
            }

PersistenceInfoProvider.cs

    /// <summary>Inits TutorsEntity's mappings</summary>
    private void InitTutorsEntityMappings()
    {
        base.AddElementMapping( "TutorsEntity", "test", @"Default", "tutors", 20 );

** base.AddElementFieldMapping( "TutorsEntity", "Tid", "tid", false, (int)MySqlType.Int, 0, 0, 10, true, "LAST_INSERT_ID()", null, typeof(System.Int64), 0 )**; base.AddElementFieldMapping( "TutorsEntity", "Fname", "fname", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 1 ); base.AddElementFieldMapping( "TutorsEntity", "Mname", "mname", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 2 ); base.AddElementFieldMapping( "TutorsEntity", "Preferredname", "preferredname", true, (int)MySqlType.VarChar, 100, 0, 0, false, "", null, typeof(System.String), 3 ); base.AddElementFieldMapping( "TutorsEntity", "Lname", "lname", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 4 ); base.AddElementFieldMapping( "TutorsEntity", "Gender", "gender", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 5 ); base.AddElementFieldMapping( "TutorsEntity", "Ssn", "ssn", true, (int)MySqlType.VarChar, 11, 0, 0, false, "", null, typeof(System.String), 6 ); base.AddElementFieldMapping( "TutorsEntity", "Dateadded", "dateadded", true, (int)MySqlType.Date, 0, 0, 0, false, "", null, typeof(System.DateTime), 7 ); base.AddElementFieldMapping( "TutorsEntity", "Rating", "rating", true, (int)MySqlType.Float, 0, 0, 0, false, "", null, typeof(System.Single), 8 ); base.AddElementFieldMapping( "TutorsEntity", "Status", "status", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 9 ); base.AddElementFieldMapping( "TutorsEntity", "Notes", "notes", true, (int)MySqlType.Text, 65535, 0, 0, false, "", null, typeof(System.String), 10 ); base.AddElementFieldMapping( "TutorsEntity", "Hired", "hired", true, (int)MySqlType.TinyInt, 0, 0, 4, false, "", null, typeof(System.Int16), 11 ); base.AddElementFieldMapping( "TutorsEntity", "Datehired", "datehired", true, (int)MySqlType.Date, 0, 0, 0, false, "", null, typeof(System.DateTime), 12 ); base.AddElementFieldMapping( "TutorsEntity", "IseeExp", "isee_exp", true, (int)MySqlType.TinyInt, 0, 0, 1, false, "", null, typeof(System.Int16), 13 ); base.AddElementFieldMapping( "TutorsEntity", "Officenotes", "officenotes", true, (int)MySqlType.Text, 65535, 0, 0, false, "", null, typeof(System.String), 14 ); base.AddElementFieldMapping( "TutorsEntity", "Editschedulefirsttime", "editschedulefirsttime", true, (int)MySqlType.TinyInt, 0, 0, 4, false, "", null, typeof(System.Int16), 15 ); base.AddElementFieldMapping( "TutorsEntity", "SatExp", "sat_exp", true, (int)MySqlType.TinyInt, 0, 0, 1, false, "", null, typeof(System.Int16), 16 ); base.AddElementFieldMapping( "TutorsEntity", "TutorType", "tutor_type", true, (int)MySqlType.VarChar, 50, 0, 0, false, "", null, typeof(System.String), 17 ); base.AddElementFieldMapping( "TutorsEntity", "Mugshot", "mugshot", true, (int)MySqlType.Blob, 2147483647, 0, 0, false, "", null, typeof(System.Byte[]), 18 ); base.AddElementFieldMapping( "TutorsEntity", "NclbDocPath", "nclb_doc_path", true, (int)MySqlType.VarChar, 255, 0, 0, false, "", null, typeof(System.String), 19 ); }

kbelange wrote:

I'm not sure what you mean by the DDL, so i'll attach the entity class & the db specific entity type mapping class. I'll also see where the entity gets fetched and post that, but don't laugh - it's not my code and it's pretty ugly (they have an if statement with 7 almost identical cases - one for each day of the week, total cut & paste)

Otis wrote:

Just to rule out any miscommunication: could you please paste me the DDL of the table this Tid field is in so I have a 100% the same testcase here and we're talking about the exact same thing? (and if you could, please post the code you use to fetch the entity).

About 4.1 -> 5.0, I don't think it's related to that, I also tested this on 4.1, as you used that too, so I don't think it will make a difference. It's pure a way of how a 32bit unsigned value will be mapped onto a .net type: you can't map an unsigned 32bit int onto a normal int32 type in .net, so corelab choose to use an int64, which is understandable, as uint is not cls compliant.

(edit): the screenshot you posted shows that the Tid is indeed unsigned, so you should get back an int64. I'll check out what the 3.5x provider does with that kind of fields, though it would surprise me if that would be an int32, simply because I know for a fact people are using 3.5x with llblgen pro and int fields and it works ok, and I can't imagine corelab has now decided to drop the int64, but on the other hand, nothing is impossible with these guys so I'll try to repro it on another box, with 3.55 installed connecting to mysql 4.1x

Attachments
Filename File size Added on Approval
TutorsEntity.zip 6,031 15-Dec-2006 21:45.31 Approved
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 16-Dec-2006 13:19:00   

I have the same type for the ID: int(10) unsigned PK auto_increment.

Here it results in an int64 value as I've posted earlier. So, a couple of things: - (silly question, forgive me) At runtime, do you really connect to the same MySql database as you connect to when you created the project? - When you use DataAccessAdapter.FetchDataReader, to fetch all Tid's from that table, what's the value for Tid as reported by the datareader? If it's int32, please contact Corelab and ask them why this is, as I get Int64's.

Frans Bouma | Lead developer LLBLGen Pro
kbelange
User
Posts: 40
Joined: 07-Dec-2006
# Posted on: 16-Dec-2006 20:01:57   

Not a silly question at all, but i have only one database - unless MySQL is doing some weird kind of versioning of my schema without me knowing, there's no way - i only have one connection set up in the Query and Admin tools. I am using InnoDB, if that matters, but i believe you recommend that, no?

Ok, i did your test and it does return Int64 (had to learn how to use the FetchDataReader but i'm a quick learner simple_smile (your docs are quite good, but i got a bit confused at first thinking that i had to use a stored procedure, until i saw the 2nd example using this method:

        TutorApp.HelperClasses.ResultsetFields fields = new TutorApp.HelperClasses.ResultsetFields( 1 );
        fields[0] = TutorApp.HelperClasses.TutorsFields.Tid;
        System.Data.IDataReader reader = da.FetchDataReader(fields, null, System.Data.CommandBehavior.CloseConnection, 100, null, false);
        object theValue;
        if (reader.Read())
        {
            theValue = reader[0];
        }

So does that mean there's something wrong with the way the entity is being fetched or queried in the problematic code?

Otis wrote:

I have the same type for the ID: int(10) unsigned PK auto_increment.

Here it results in an int64 value as I've posted earlier. So, a couple of things: - (silly question, forgive me) At runtime, do you really connect to the same MySql database as you connect to when you created the project? - When you use DataAccessAdapter.FetchDataReader, to fetch all Tid's from that table, what's the value for Tid as reported by the datareader? If it's int32, please contact Corelab and ask them why this is, as I get Int64's.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 18-Dec-2006 12:27:53   

Hmm... if it does return an int64, I have no idea how it becomes an int32, because all I do is call GetValues() on the datareader and store the values in the CurrentValue properties of the fields, so if the reader returns an int64 (as you found out), an int64 is stored in the Field's CurrentValue property...

Frans Bouma | Lead developer LLBLGen Pro
1  /  2