Dapper.Contrib icon indicating copy to clipboard operation
Dapper.Contrib copied to clipboard

`Insert` method always returns 0 when using [ExplicitKey].

Open Caltor opened this issue 7 years ago • 1 comments

If your table has a user generated key you need to generate the key property with the [ExplicitKey] attribute as per the Contrib docs. Example:

public class Employee
{
    [ExplicitKey]
    public int Id { get; set; }
    public string Name { get; set; }
    // etc etc etc
}

However the Dapper.Contrib Insert method always returns 0 meaning there is no (easy) way to determine whether or not the record was written successfully. Can you change this please so that the Id is returned to indicate success or 0 is returned for failure as it does when using a system generated key.

Caltor avatar Apr 26 '17 15:04 Caltor

Here is a failing test for you.

using System;
using System.Data.SqlClient;
using Dapper;
using Dapper.Contrib.Extensions;
using System.Diagnostics;

namespace TestConsoleApplication
{
	class WithSystemKey
	{
		[Key]	// not really needed as key property is called 'id' case-insensitive
		public int Id { get; set; }		// This Id is auto-generated by SQL
		public string Info { get; set; }
	}

	class WithUserKey
	{
		[ExplicitKey]
		public int Id { get; set; } // This Id is generated by user code
		public string Info { get; set; }

	}

	class Program
	{
		static void Main(string[] args)
		{
			// Arrange
			SqlConnection Conn = new SqlConnection(@"Data Source=(local)\SQLEXPRESS;Initial Catalog=Master;Integrated Security=True");
			Conn.Execute(@"IF EXISTS(SELECT * FROM sys.databases WHERE name='TestDB') DROP DATABASE TestDB");
			Conn.Execute(@"CREATE DATABASE [TestDB]");

			Conn = new SqlConnection(@"Data Source=(local)\SQLEXPRESS;Initial Catalog=TestDB;Integrated Security=True");
			Conn.Execute(@"USE [TestDB]");
			Conn.Execute(@"
CREATE TABLE[dbo].[WithSystemKeys](
	[Id] [int] IDENTITY(1,1) NOT NULL,
    [Info] [nvarchar](max) NULL
);
");

			Conn.Execute(@"
CREATE TABLE [dbo].[WithUserKeys](
	[Id] [int] NOT NULL,
	[Info] [nvarchar](max) NULL
);
");

			// Act
			long id1 = Conn.Insert<WithSystemKey>(new WithSystemKey() { Info = "I have a system generated key" });
			int userId = 1;
			long id2 = Conn.Insert<WithUserKey>(new WithUserKey() { Id = userId, Info = "I have a user specified key" });

			// Assert
			Debug.Assert(id1 > 0, $"Insert should return system generated key.\r\nExpected: > 0\r\nGot: {id1}");	// Passes
			Debug.Assert(id2 == 1, $"Insert should return user specified key.\r\nExpected: {userId}\r\nGot: {id2}");	// Fails

		}
	}
}


Caltor avatar Apr 27 '17 11:04 Caltor