[英]Can I use DynamicParameters with Template and have a return parameter in dapper?
[英]Can I remove a parameter from the Dapper DynamicParameters?
我正在从外部来源检索数据。 我的课程与 JSON 的响应相匹配。 但是 json 中有一个内部对象。 当我将它传递给 Dapper 中的动态参数时,如何删除它?
类的基本结构
{
"name": "John",
... 30 more fields here ...
"location": {
"city": "abcd",
"zip": "87123"
}
}
像这样使用:
foreach (var result in response.results)
{
var parameters = new DynamicParameters();
parameters.AddDynamicParams(result);
// I need to remove "location" from this parameter
// and then I can add the city and zip
parameters.AddDynamicParams(result.location.city); // etc
db.Execute("save_data", parameters, commandType:CommandType.StoredProcedure);
}
仍在等待答案,但这是我开始使用的解决方法
foreach (var result in response.results) {
var parameters = new DynamicParameters();
foreach (PropertyInfo prop in result.GetType().GetProperties()) {
if (!SpecialParameter(result, prop, parameters))
parameters.Add(prop.Name, prop.GetValue(result, null));
}
db.Execute("save_data",
parameters, commandType: CommandType.StoredProcedure);
}
function SpecialParameter(result, prop, parameters) {
// can be implemented in the sub class
switch (prop.Name) {
case "location":
parameters.Add("location_city", result.city);
parameters.Add("location_state", result.city);
return true;
}
return false;
}
我希望能够发送 Dapper 强类型而不是匿名对象,例如:
var myObject = new MyClass{
MyProperty = 1
};
_connection.ExecuteAsync(
"InsertStoredProcedure",
myObject,
commandType: CommandType.StoredProcedure
)
这工作得很好,但是假设MyClass
有一个Id
int 会在数据库中自动递增。 我不需要将它作为参数传递,并且我不想更新我的存储过程来获取一个不会被使用的虚拟 id 参数。
幸运的是,如果你给它一个字典版本的对象,Dapper 的 DynamicParameters 构造函数知道该怎么做,所以使用反射你可以将它转换为字典,删除你不需要的任何字段,然后从中创建一组 DynamicParameters。
现在的问题是如何一般地做到这一点。 如果您有很多不同的实体要与 Dapper 一起使用,您不希望每次都将它们转换为字典并删除不需要的字段。 你可以通过创建一个属性来解决这个问题。
[AttributeUsage(AttributeTargets.Property)]
public class DapperIgnore : Attribute {}
然后用你想忽略的字段来装饰你的班级。
public class MyClass {
[DapperIgnore]
public long Id {get; set;}
public int MyProperty {get; set;}
}
现在您可以创建一个包装 Dapper 版本的扩展方法。
public static async Task<int> ExecuteWithTypeAsync<TInput>(
this IDbConnection cnn,
string sql,
TInput input,
IDbTransaction transaction = null,
int? commandTimeout commandTimeout = null,
CommandType? commandType = null
){
var dictionary = typeof(TInput).GetProperties()
.Where(property => property
.GetCustomAttributes(false)
.All(attr => attr is not DapperIgnore)
)
.ToDictionary(x => x.Name, x => x.GetValue(input));
var parameters = new DynamicParameters(dictionary);
return await cnn.ExecuteAsync(sql, parameters, transaction, commandTimeout, commandType);
}
请注意,您应该将该方法命名为与其包装的 Dapper 方法不同的名称——即使您添加了一个类型参数——否则这将成为到处使用的新方法,即使对于匿名对象也是如此。
现在你可以做
_connection.ExecuteWithTypeAsync(
"InsertStoredProcedure",
myObject,
commandType: CommandType.StoredProcedure
)
...并且它不会包含您使用 [DapperIgnore] 属性修饰的Id
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.