-1

Database table:

CREATE TABLE [dbo].[EmployeeDetails]
(
    [id] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,
    [Name] [varchar](max) NULL,
    [Emailid] [varchar](max) NULL,
    [department] [varchar](max) NULL,
    [Salary] [int] NULL,
    [Profile] [varchar](max) NULL,
    [Description] [varchar](max) NULL,
    [ReferencesId] [int] NULL
)

Model class:

public class Employee
{
    #region properties
    public int Id { get; set; }
    public string? Name { get; set; }
    public string? Emailid { get; set; }
    public string? department { get; set; }

    public int salary { get; set; }

    public string? Profile { get; set; }
    public string? Description { get; set; }
    #endregion
}

ClassMappper

public class EmployeeMapper : ClassMapper<Employee>
{
    public EmployeeMapper() 
    {
        Table("EmployeeDetails");

        Map(x => x.Id).Key(KeyType.Identity).Column("Id").Type(System.Data.DbType.Int32);           
        Map(x => x.Name).Column("Name");
        Map(x => x.Emailid).Column("Emailid");
        Map(x => x.department).Column("department");
        Map(x => x.salary).Column("Salary");
        Map(x => x.Profile).Column("Profile");
        Map(x => x.Description).Column("Description");
    }
}

Insert code:

public int Add(T entity)
{
    int count = 0;

    using (var con = _dapperContext.CreateConnection())
    {
        int id = con.Insert(entity);

        if (id > 0)
        {
            count++;
        }
    }

    return count;
}

I get this error:

enter image description here

System.ArgumentException: 'Object of type 'System.Int64' cannot be converted to type 'System.Int32'.'

I show this exception on the page but data is inserted in database successfully. My database datatype and model class datatypes both are the same, but I still get this "Conversion Error" on the page

I need insert one new row into the database table using Dapper Extension in ASP.NET Core Razor page

enter image description here

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 4
    Can you please show the complete stack trace (as text, not as image, please) – Klaus Gütter Jan 26 '23 at 05:21
  • System.ArgumentException HResult=0x80070057 Message=Object of type 'System.Int64' cannot be converted to type 'System.Int32'. Source= StackTrace: – Kudiyarasu M Jan 26 '23 at 05:24
  • 7
    You had **just asked** this very same question not even a day ago: https://stackoverflow.com/questions/75231884/dapper-extension-insert-using-sql-server - please **DO NOT** repost the same question over and over again – marc_s Jan 26 '23 at 05:27
  • Please show your database table schema, not just the create script. – OJ Raqueño Jan 26 '23 at 05:29
  • Does this answer your question? [Dapper Extension insert using SQL Server](https://stackoverflow.com/questions/75231884/dapper-extension-insert-using-sql-server) – sa-es-ir Jan 26 '23 at 05:30
  • Yes , I changed Salary Datatype in Db Bigint to int till show same exception – Kudiyarasu M Jan 26 '23 at 05:32
  • `"but I still get this "Conversion Error" on the page"` Can you attach your page as well? Need to check how you are sending request? – Md Farid Uddin Kiron Jan 26 '23 at 05:48
  • You are getting the exception because of your return type `count;` not sure how you aree doing in your view page with `count;` – Md Farid Uddin Kiron Jan 26 '23 at 05:55
  • Include your view page code, you of course doing some mess there. In addition, what the details of `_dapperContext`? – Md Farid Uddin Kiron Jan 26 '23 at 06:00
  • @marc_s , I have reeproduced the issue, seems OP's asking is valid. However, the approach is very ugly, Issue is in dapper extension. I am working on it. Thus, OP, owns a upvote. – Md Farid Uddin Kiron Jan 26 '23 at 07:09
  • View page code means – Kudiyarasu M Jan 26 '23 at 07:15
  • A complete stack trace would show where the exception is originating from and so answer the question. Possibly you're doing 64 bit compilation. In SQL Server the `int` data type is always 32 bits. Have you tried changing `public int Id { get; set; }` to `public Int32 Id { get; set; }` in your `Employee` class? – AlwaysLearning Jan 26 '23 at 07:40
  • Aside... do you really need `varchar(max)` columns to store 2GB long names, email addresses, departments, etc.? Consider using more appropriate lengths (or even make educated guesses based on your data requirements) and then in your class mapper be sure to include a call to the `.Size(lengthOfTheDatabaseColumnHere)` method to match. – AlwaysLearning Jan 26 '23 at 07:55
  • Please add code and data as text ([using code formatting](/editing-help#code)), not images. Images: A) don't allow us to copy-&-paste the code/errors/data for testing; B) don't permit searching based on the code/error/data contents; and [many more reasons](//meta.stackoverflow.com/a/285557). Images should only be used, in addition to text in code format, if having the image adds something significant that is not conveyed by just the text code/error/data. – Jim G. Jan 30 '23 at 21:45

2 Answers2

0

I show this exception on the page but data is inserted in database successfully. My database datatype and model class datatypes both are the same, but I still get this "Conversion Error" on the page

Well, at the beginning I was thinking you are doing something silly. Out of my curiosity, I get into it and got to know issue is not within your code its Dapper-Extensions issue. I have investigate quite a long while with their document and seems its older version and currently they are not supporting it. I have gone through this official document.

Issue Reproduced:

I have have reproduced the issue which has been thrown from Dapper-Extensions method as can be seen below:

Dapper Extension Method:

enter image description here

Exception:

enter image description here

Stacktrace:

at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
   at DapperExtensions.DapperImplementor.InternalInsert[T](IDbConnection connection, T entity, IDbTransaction transaction, Nullable`1 commandTimeout, IClassMapper classMap, IList`1 nonIdentityKeyProperties, IMemberMap identityColumn, IMemberMap triggerIdentityColumn, IList`1 sequenceIdentityColumn)
   at DapperExtensions.DapperImplementor.Insert[T](IDbConnection connection, T entity, IDbTransaction transaction, Nullable`1 commandTimeout)
   at MVCApps.Controllers.UserLogController.Add() in D:\MyComputer\MsPartnerSupport\MVCApps\Controllers\UserLogController.cs:line 1371
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()

Note:

While debugging and reproduce the issue, I have tried to use data type both int in both side as well as other data type for instance, bigint but still that conversion error taken place and I found this issue is known in regards of Dapper-Extensions. Thus, one data-type works out accordingly that is GUID. I still not sure, how these Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast are Intervening here.

Solution-Work Around:

As of now, int, bigint always throws 'Object of type 'System.Int64' cannot be converted to type 'System.Int32'.' hence, the reason is not clear which coming from DapperExtensions.DapperExtensions.Insert() method.

Furthermore, to avoid above error, we can do as following:

POCO Model:

public class Employee
    {

        public Guid Id { get; set; }
        public string Name { get; set; }
        public string Emailid { get; set; }
        public string Department { get; set; }
        public int Salary { get; set; }
    }

Note:

Other than Guid currently not working, I am not sure the reason behind this. So if you would like to stick to your implementation, you could consider Guid.

Database Schema:

CREATE TABLE Employee(
      [Id] UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
      [Name] [varchar](25) NULL,
      [Emailid] [varchar](100) NULL,
      [Department] [varchar](25) NULL,
      [Salary] [int] NULL,
)

enter image description here

Asp.Net Core Controller/Repository Method:

public int Add()
        {
            int count = 0;

            Employee employee = new Employee();
            employee.Name = "Kudiya";
            employee.Emailid = "email@someemail.com";
            employee.Department = "Dapper";
            employee.Salary = 500;
            using (SqlConnection conn = new SqlConnection(_connectionString))
            {
                conn.Insert(employee);
                Guid Id = employee.Id;
               
                if (Id != null)
                {
                    count++;
                }
            }
            return count;
        }

Note: Please update the code snippet based on your scenario and context.

Output:

enter image description here

Note: Moreover, based on the stacktrace, if someone has the exact explnation or findings, please do let me know. I wound happy to update my answer.

Md Farid Uddin Kiron
  • 16,817
  • 3
  • 17
  • 43
  • Ultimately it seems the problem is buried inside the [DapperImplementation.InsertIdentity(...)](https://github.com/tmsmith/Dapper-Extensions/blob/master/DapperExtensions/DapperImplementor.cs#L610) method which assumes that the returned identity will always be `long` (`Int64`). The value is returned to `InternalInsert(...)` and applied via `column.SetValue(...)` at which point the exception gets thrown. Probably they need alternate implementations of `InsertIdentity` that return `Int32` or `Int64` as appropriate, or a smarter variant version. – AlwaysLearning Jan 26 '23 at 09:12
  • Yes, absolutely inside `DapperImplementation.InsertIdentity(...) ` , I have tried with both `Int64` and `Int32` but still the error persisted. So I decided to go with GUID and works out. – Md Farid Uddin Kiron Jan 26 '23 at 09:17
  • what is UNIQUEIDENTIFIER? – Kudiyarasu M Jan 27 '23 at 03:48
  • Well, as you may know `Guid` create unique id, so in database, corresponding datatype is `UNIQUEIDENTIFIER` just like primary key which never be duplicate. You can [`check here`](https://learn.microsoft.com/en-us/sql/t-sql/data-types/constants-transact-sql?view=sql-server-ver16#uniqueidentifier-constants). – Md Farid Uddin Kiron Jan 27 '23 at 04:09
0

Model:


 [Table("ClientAccount")]
    public class ClientAccount
    {
        public long ID { get; set; }
    }

Repository:

 using (IDbConnection conn = GetConnection())
   {              
    var result = await conn.InsertAsync<ClientAccount>(clientAccount);                    
   }

The above worked for me. instead of int, I used long for ID column and in the repository, getting result as var not as int.

abolfazl sadeghi
  • 2,277
  • 2
  • 12
  • 20
Naveen
  • 43
  • 8