Dapper Extensions 自定义 ClassMapper 未在 Insert() 上调用

Dapper Extensions custom ClassMapper isn't called on Insert()

我正在使用 Dapper Extensions 并定义了我自己的自定义映射器来处理具有复合键的实体。

     public class MyClassMapper<T> : ClassMapper<T> where T : class
{
    public MyClassMapper()
    {
        // Manage unmappable attributes

        IList<PropertyInfo> toIgnore = typeof(T).GetProperties().Where(x => !x.CanWrite).ToList();

        foreach (PropertyInfo propertyInfo in toIgnore.ToList())
        {
            Map(propertyInfo).Ignore();
        }

        // Manage keys

        IList<PropertyInfo> propsWithId = typeof(T).GetProperties().Where(x => x.Name.EndsWith("Id") || x.Name.EndsWith("ID")).ToList();
        PropertyInfo primaryKey = propsWithId.FirstOrDefault(x => string.Equals(x.Name, $"{nameof(T)}Id", StringComparison.CurrentCultureIgnoreCase));

        if (primaryKey != null && primaryKey.PropertyType == typeof(int))
        {
            Map(primaryKey).Key(KeyType.Identity);
        }
        else if (propsWithId.Any())
        {
            foreach (PropertyInfo prop in propsWithId)
            {
                Map(prop).Key(KeyType.Assigned);
            }
        }

        AutoMap();
    }
}

我也有这个测试用例来测试我的映射器:

    [Test]
    public void TestMyAutoMapper()
    {
        DapperExtensions.DapperExtensions.DefaultMapper = typeof(MyClassMapper<>);

        MySubscribtionEntityWithCompositeKey entity = new MySubscribtionEntityWithCompositeKey
        {
            SubscriptionID = 145,
            CustomerPackageID = 32
        };

        using (var connection = new SqlConnection(CONNECTION_STRING))
        {
            connection.Open();
            var result = connection.Insert(entity);
            var key1 = result.SubscriptionID;
            var key2 = result.CustomerPackageID;
        }
    }

请注意,我在测试用例中设置了默认映射器。

插入失败,我注意到从未调用我的客户映射器。我在 github 页面上没有关于该主题的文档,所以我不确定是否还需要做任何其他事情才能使 dapper 扩展使用我的映射器。

提前致谢!

看看你的问题,你正在试图编写你自己的defalutclass映射器,它是从现有映射器派生出来的。我从未使用过这种方法;所以我不知道为什么它不起作用或它是否应该起作用。

我明确映射 classes 如下:

public class Customer
{
    public int CustomerID { get; set; }
    public string Name { get; set; }
}

public sealed class CustomerMapper : ClassMapper<Customer>
{
    public CustomerMapper()
    {
        Schema("dbo");
        Table("Customer");
        Map(x => x.CustomerID).Key(KeyType.Identity);
        AutoMap();
    }
}

AutoMap() 将根据 conventions. Please refer to these two 资源映射其余属性,以获取有关映射的更多信息。

然后我在项目启动时调用SetMappingAssemblies如下:

DapperExtensions.DapperExtensions.SetMappingAssemblies(new[] { Assembly.GetExecutingAssembly() });

GetExecutingAssembly() 在上面的代码中使用,因为映射 classes(CustomerMapper 和其他)在正在执行的同一程序集中。如果那些 classes 被放置在其他程序集中,请提供 that 程序集。

就是这样,它有效。

要设置方言,我在 SetMappingAssemblies 下方调用以下行:

DapperExtensions.DapperExtensions.SqlDialect = new DapperExtensions.Sql.SqlServerDialect();

使用您喜欢的方言而不是 SqlServerDialect

显然,here 中提到的解决方案可能会帮助您实现您的实际目标。但是,我不能确定,正如我上面所说,我从未使用过它。