Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VS 2015 compiler fails when providing custom implementation of SqlMapper.enumParse #448

Closed
nCubed opened this issue Feb 1, 2016 · 1 comment

Comments

@nCubed
Copy link

nCubed commented Feb 1, 2016

We are using Dapper in a large enterprise winform application. Currently, we are in the process of upgrading our project targets from VS 2013 / .NET 4.5.2 to VS 2015 / .NET 4.6.1.During testing, we found that our Dapper repositories were failing when running under VS 2015.

Specifically, we have unique requirements for handling Enums and have had to take a direct file reference to Dapper which allows us to remove the readonly modifier on the SqlMapper.enumParse field and provide our own implementation which was worked as expected for over a year now.

We've isolated the issue down to what we believe is a difference in the VS 2013 compiler and VS 2015 compiler. Running under VS 2013, there are no issues with providing our own implementation of SqlMapper.enumParse. Under VS 2015, we receive a DataException: "An unhandled exception of type 'System.Data.DataException' occurred..." and the error points to the parsing of the enum.

The following is the bare minimum to reproduce the issue:

  • Set up a solution and target .NET v4.5 to 4.6.1
  • Drop in the code that follows the end of this post.
  • Use the latest Dapper code and remove the SqlMapper.enumParse readonly modifier.

Of Note:

  • The sample code resets the SqlMapper.enumParse field with a different implementation than the native Dapper code which uses the standard .NET Enum.Parse method.
  • The underlying SQL always returns the Product.ProductType as ProductType.Gmo; the implementation of SqlMapper.enumParse will always set the enum to ProductType.Organic.
  • Running under VS 2013, the expected results are produced where the Product.ProductType enum will always be ProductType.Organic. Under VS 2015, an exception occurs.

I realize this is not a Dapper specific issue, but was hoping you could provide some guidance on why this is occuring with the VS 2015 compiler?

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using Dapper;
using DapperRoslyn;

namespace Dapper
{
    static partial class SqlMapper
    {
        internal static void SetEnumParse()
        {
            Func<Type, string, bool, object> dapperEnum = ( type, value, flag ) => ToEnum( type, value );
            enumParse = dapperEnum.Method;
        }

        private static object ToEnum( Type type, string value )
        {
            return ProductType.Organic;
        }
    }
}

namespace DapperRoslyn
{
    class Program
    {
        const string ConnectionString = "Data Source=.;Initial Catalog=.;Integrated Security=True";

        static void Main()
        {
            SqlMapper.SetEnumParse();

            var repo = new ProductRepository( ConnectionString );

            var products = repo.GetAll();

            foreach( Product product in products )
            {
                Console.WriteLine( product );
            }

            Console.ReadLine();
        }
    }

    public class ProductRepository
    {
        private readonly string _connectionString;

        public ProductRepository( string connectionString )
        {
            _connectionString = connectionString;
        }

        public IEnumerable<Product> GetAll()
        {
            const string sql = @"
create table #Product(Name nvarchar(25) not null, ProductType nvarchar(25) not null)

insert into #Product(Name, ProductType)
values
 ('Banana', 'Gmo')
,('Orange', 'Gmo')
,('Pear', 'Gmo')
,('Apple', 'Gmo')
,('Strawberry', 'Gmo')

Select Name, ProductType from #Product

drop table #Product
";

            using( var conn = new SqlConnection( _connectionString ) )
            {
                var results = conn.Query<Product>( sql, commandType: CommandType.Text );

                return results.ToList();
            }
        }
    }

    public enum ProductType
    {
        Unknown = 0,
        Gmo = 1,
        Organic = 2,
    }

    public class Product
    {
        public string Name { get; set; }

        public ProductType ProductType { get; set; }

        public override string ToString()
        {
            return string.Format( "{0} {1}", Name, ProductType );
        }
    }
}
@NickCraver
Copy link
Member

Trying to follow-up and classify all existing issues here. We're going to look at type handlers (to fix the reason for using source here) in v3, but as it relates to this issue Dapper is not supported as a source package any longer (hasn't been for years). We routinely use the latest version and features of C#, so if you're using an older compiler it'll very often not yield expected results and...well, be a PITA.

I'll update #694 as we get to type handlers in v3, but closing this out to cleanup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants