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 中提到的解决方案可能会帮助您实现您的实际目标。但是,我不能确定,正如我上面所说,我从未使用过它。
我正在使用 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 中提到的解决方案可能会帮助您实现您的实际目标。但是,我不能确定,正如我上面所说,我从未使用过它。