Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Dapper.Contrib.Extensions is a great addition to Dapper but it does not seem to support custom mapping. For instance when I pass an entity to Insert(...) it looks like the only attributes used are Table/Key/ExplicitKey/Write/Computed. In my case I have a simple class 'Notifications' with a string property Username and I just want to map that property to username. The only customizable part I found in SqlMapperExtensions is TableNameMapper, nothing for custom mapping.

The (ugly) workaround I found to insert items is to convert my class to an anonymous type with the correct column names and add that anonymous to TableNameMapper

Can you please let me know if I missing anything?

My code:

using Npgsql;
using Dapper.Contrib.Extensions;

namespace DapperTest
{
    class Program
    {
        static void Main(string[] args)
        {
            IDbConfig config = // get config
            string cntString =
                $"Host={config.Host};Port={config.Port};User Id={config.Username};Password={config.DecryptedPassword};Database={config.Database};";
            IDbConnection cnt = new NpgsqlConnection(cntString);
            cnt.Open();

            var n = new Notification
            {
                Username = "test",
                Message = "This is a test"
            };

            object id = cnt.Insert(n);
        }
    }

    public class Notification
    {
        [Key]
        public int Id { get; set; }    
        public string Username { get; set; }        
        public string Message { get; set; }
    }
}

Exception: Npgsql.PostgresException: '42703: column "Username" of relation "notifications" does not exist'

Which makes sense because my column name is indeed 'username' (lowercase) in Postgres

And with my (super ugly hack):

    var n = new Notification
    {
        Username = "test",
        Message = "This is a test"
    };

    // I remap my object to an anonymous type with correct columns
    var a = new
    {
        username = n.Username,
        message = n.Message
    };

    // I map that anonymous to the 'notifications' table
    SqlMapperExtensions.TableNameMapper = (type) => {
        return "notifications";
    };

    // But id is not returned because Id/id property no longer has the [Key] attribute
    object id = cnt.Insert(a);

Thanks!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.5k views
Welcome To Ask or Share your Answers For Others

1 Answer

With Dapper.Contrib, you can decorate the class with [Table] attribute to map the table name. Alternatively, you can use SqlMapperExtensions.TableNameMapper to map the tables. Please refer to this blog post or this SO post for more details.

Apparently, there is no way to map the column name. This feature is planned for next major version. But there are multiple alternatives discussed in this Q/A as mentioned in comment by @PalleDue. Although most of them are suggested for Dapper, many of them also work for Dapper-Contrib.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...