我正在使用普通Dapper为项目实现数据访问层。我正在使用CRUD操作的通用存储库和我的查询的通用查询构建器。
在查询构建器中注释属性和访问注释时出现问题。我之前使用过实体框架,虽然它非常擅长抽象,但它有性能瓶颈,这个项目可能不适合。
我的模型是这样的: -
[ModelAttributes(Key = "CubeID")]
public class RepSysCube
{
public int CubeID { get; set; }
public int ApplicationID { get; set; }
public int AuthorisationID { get; set; }
public string CubeName { get; set; }
public string CubeDescription { get; set; }
public byte[] Image { get; set; }
}
ModelAttribute是这样的: -
[AttributeUsage(AttributeTargets.Class)]
internal class ModelAttributes : System.Attribute
{
private string _Key;
public string Key
{
get
{
return _Key;
}
set
{
_Key = value;
}
}
}
我的存储库是这样的: -
public class Repository<T> : IRepository<T> where T : class
{
public T GetById(int id)
{
string query = queryBuilder.SelectByID(id);
var queryResult = dbConnection.Query<T>(query);
return queryResult.FirstOrDefault();
}
}
现在生成我的查询我可以使用这样的东西: -
internal class QueryBuilder<T> : IQueryBuilder<T> where T : class
{
string _Query = string.Empty;
public string SelectByID(int ID)
{
_Query = string.Format("SELECT * FROM {0} WHERE {1} = '{2}'", typeof(T).Name, ((ModelAttributes)typeof(T).GetCustomAttributes(false).Where(x => x == (ModelAttributes)x).First()).Key, ID);
return _Query;
}
}
我的问题是使用
((ModelAttributes)typeof(T).GetCustomAttributes(false).Where(x => x == (ModelAttributes)x).First()).Key
我知道C#中的Reflection有性能成本。还有其他方法我可以实现类似的东西,我可以很容易地确定Model类的特征。
我尝试在Model类中使用一个函数,但令我沮丧的是,我无法使用T调用该函数。
因为通用静态变量的类型不同,即QueryBuilder<Car>.KeyField
是一个与QueryBuilder<Truck>.KeyField
不同的变量,你只能执行一次反射,只需使用变量值进行后续调用,每次调用方法时都要删除调用反射的费用(重要与否) 。
internal class QueryBuilder<T> : IQueryBuilder<T> where T : class
{
private static readonly string KeyField = ((ModelAttributes)typeof(T).GetCustomAttributes(false).Where(x => x == (ModelAttributes)x).First()).Key;
private string _Query = string.Empty;
public string SelectByID(int ID)
{
// don't create your query this way. use a parameterized query
_Query = string.Format("SELECT * FROM {0} WHERE {1} = '{2}'", typeof(T).Name, KeyField, ID);
return _Query;
}
}