Pomelo.EntityFrameworkCore.MySql icon indicating copy to clipboard operation
Pomelo.EntityFrameworkCore.MySql copied to clipboard

Datatype Set is missing

Open barathistvan91 opened this issue 5 years ago • 3 comments

The issue

When I call the Scaffold-DbContext command and I have a column with "set" datatype then I get this warning message: "Could not find type mapping for column 'table.columnname' with data type 'set('Value A','Value B')'. Skipping column."

I do not see the mapping in the MySqlTypeMappingSource.cs. I have found a commit by google from about 2017 and there was something about the set type in it but I do not find yet.

Should it map to string or string[]?

Further technical details

MySQL version: 10.4.11-MariaDB Operating system: Windows 10 Pomelo.EntityFrameworkCore.MySql version: 2.2.6 Microsoft.AspNetCore.App version: v2.2.0

barathistvan91 avatar Feb 11 '20 23:02 barathistvan91

I do not see the mapping in the MySqlTypeMappingSource.cs.

Yes, unfortunately we don't support the set store type yet.

Should it map to string [...]

As a workaround, you should be able to accomplish this without much work by taking the example code from https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/issues/693#issuecomment-572045842 (especially the JsonStringTypeMappingSourcePlugin class) and replacing all occurrences of json with set, Json with Set and JSON with SET, if you just want to map the set store type to a System.String.

lauxjpn avatar Feb 13 '20 10:02 lauxjpn

Thank you the guide! I had to tweak a little bit but now it is working with Scaffold-DbContext

    public class CustomTypeMappingSourcePlugin : IRelationalTypeMappingSourcePlugin, IDesignTimeServices
    {
        private static MySqlStringTypeMapping _json;

        public CustomTypeMappingSourcePlugin()
        {
            _json = new MySqlStringTypeMapping("json", DbType.String);
        }

        public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
        {

            serviceCollection.AddSingleton<IRelationalTypeMappingSourcePlugin, CustomTypeMappingSourcePlugin>();
        }

        public RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo)
        {
            // Console.WriteLine(mappingInfo.StoreTypeName);

            if (string.Equals(mappingInfo.StoreTypeName, "json", StringComparison.OrdinalIgnoreCase))
            {
                return _json;
            }

            if (mappingInfo.StoreTypeName != null && mappingInfo.StoreTypeName.StartsWith("set("))
            {
                return new MySqlStringTypeMapping(mappingInfo.StoreTypeName, DbType.String);
            }
            
            return null;
        }
    }
  1. The set type name contains the whole enumeration so i have to create the mapping on the fly.
  2. I have to implemenent IDesignTimeServices to add this custom plugin at scaffolding.
  3. It is works well with the EF.Functions.Like(..) syntax because FIND_IN_SET db function is also missing from EF.

barathistvan91 avatar Feb 13 '20 19:02 barathistvan91

@barathistvan91 Thanks for sharing, looks good! (Feel free to remove all the JSON stuff if you don't need it.)

lauxjpn avatar Feb 13 '20 19:02 lauxjpn