dapper无论如何都可以将数据库中的两列映射到一个.Net数据类型? 我的情况是我在数据库中有货币值表示为两列。
Cost Decimal(19,4)
CostCurrency char(3)
我希望它映射到自定义数据类型Money
public partial struct Money
{
public Money(decimal amount, string currency)
{
}
}
例如在保险实体上:
public class Insurance
{
public string Id {get;set;}
public Money Cost {get;set;}
}
我一直在关注SqlMapper.TypeHandler<Money>
,但它似乎一次只能读/写一列。
答案 0 :(得分:2)
我倾向于发现,通过使用私有属性来表示数据存储,可以大大简化复杂属性的任何映射。 Dapper将映射到私有财产。
public class Insurance
{
#region Data
private decimal Cost{get{return this.CurrentCost.Amount;} set{this.CurrentCost.Amount = value;}}
private string Currency{get{return this.CurrentCost.Currency;} set{this.CurrentCost.Currency = value;}}
#endregion
public string Id {get;set;}
//Changed prop name to not confuse it with storage columns
public Money CurrentCost {get;set;}
public Insurance(){
//initialize this so that it won't blow up on mapping
this.CurrentCost = new Money();
}
}
乍一看,感觉就像我们正在标记我们的物体相当多,以使其坚持并映射。但它如此直截了当,没有神奇的映射,它只是起作用。您也可以对所有这些进行单元测试。即使是一个拥有数百个持久对象的项目,这项技术只会占用一小部分时间,并且在整个项目的发展过程中完全灵活和易于管理。
答案 1 :(得分:1)
原来我需要使用dapper的Split
功能:
var insurance = (await con.QueryAsync<Insurance, decimal, string, Insurance>(
sql,
(entity, cost, costCurrency) =>
{
entity.Cost = new Money(cost, costCurrency);
return entity;
},
splitOn: "Cost, CostCurrency",
param: new { Id = id })).Single();
答案 2 :(得分:0)
它不漂亮,但这是另一种选择:
var result = conn.Query(@"select Id = '1', Amount = 12.99, Currency = 'USD'
union all select Id = '2', Amount = 29.58, Currency = 'CAD'")
.Select(row => new Insurance() { Id = row.Id, Cost = new Money(row.Amount, row.Currency) })
.ToList();