Dapper处理表外字段的方法

2023年8月14日 299点热度 1人点赞 0条评论

目前我的量化交易系统已经从之前Python写的版本切换为.netCore版本。系统的数据库存储采用SQLite,ORM用的Dapper,最近在给系统扩展功能时遇到了一个实体类字段为表外字段的问题,这里记录一下处理方案。

问题的起因是K线数据实体类的扩展。在原设计中,数据库对K线进行存储的表只有OHLCV这5个维度,实际上通过某些接口,还可以拿到振幅,换手率等数据,这些数据是在做标的分析时很有用的参考,尤其是换手率。于是我考虑对原K线的实体类进行扩展,由此就引申出一个表外字段的映射问题。

关于Dapper下表外字段处理的问题,如果你的数据层实现应用了Contrib这个Dapper的扩展,那么处理起来就很方便,直接采用[Write(false)]这个特性对实体类的表外字段进行标记就可以了(using Dapper.Contrib.Extensions)。

但是如果你的Dapper没有采用Contrib,SQL是手撸的,就会有些麻烦,而我的情况就是后者。

我的解决方案是自定义Attribute。首先定义一个应用到属性上的Attribute,这个Attribute啥也不做,仅仅起到一个标记作用:

[AttributeUsage(AttributeTargets.Property)]
public class NotWriteAttribute : Attribute
{

}

然后,修改原来的Adapter层代码,通过反射读取实体类的自定义Attribute(NotWrite),如果为空,则将该属性扔进PropertyInfo数组,后面再用反射读取这个过滤后的数组生成对应的SQL,示例如下:

Type t = typeof(T);
var propertyInfo = t.GetProperties();
// 属性以NotWrite标记不进行update和insert的SQL生成
propertyInfo = propertyInfo.Where(p => p.GetCustomAttribute(typeof(NotWriteAttribute)) == null).ToArray();

过滤后的propertyInfo没有NotWrite标记,参与后续正常的SQL生成,有标记的字段在这一步通过Linq就过滤掉了。问题解决。

QThinker

前地产从业者,假装是个程序员,热爱编程与交易 自研QThinker量化交易框架

文章评论