我是ac#noobie,但这里是我要做的事情的要点:
public IEnumerable<T> GetAll<T, K>(string schemaName) where T : GenericModel
{
var sql = @"SELECT * from " +
schemaName + "." + T.getTableName() + " primaryTable LEFT JOIN " +
schemaName + "." + K.getTableName() +
" ForeignTable on ForeignTable.id = primaryTable." + T.getForeignFieldName();
return _connection.Query<T, K, T>(sql, (primary, foreign) =>
{ (primary = T.getForeignFieldName()) = foreign; return primary; });
}
例如,T = Employee,K = Person
public IEnumerable<Employee> GetAll(string schemaName)
{
var sql = @"SELECT * from " + schemaName +
".Employee primaryTable LEFT JOIN " +
schemaName + ".Person ForeignTable "+
"on ForeignTable.id = primaryTable.person_id";
return _connection.Query<EmployeeModel, PersonModel, EmployeeModel>
(sql, (primary, foreign) => { primary.person = foreign; return primary; });
}
GenericModel
有getForeignFieldName()
和getTableName()
,它们被派生类( Employee
和Person
)遮蔽
示例模型可能如下所示:
Person {
int id;
string Name;
string address;
int age;
}
Employee {
int id;
int person_id;
Person person;
double salary;
}
当然通用解决方案不起作用,我知道sql注入。我只想要一个通用的方法,我可以使用我用Dapper的Query()函数描述的方式。
换句话说,你如何编写一个可以做到这一点的通用函数: Dapper的Multi Mapping
是的,对不起,但是以最友好的方式 - 你已经偏离了预订:-)查询的创建是指定你想要的数据以及它返回的对象的那一刻。人们使用动态构造的SQL来摆弄WHERE或ORDER BY子句,但在我看来,这已经是一个完全的反模式。通过推迟关于哪些表的最终决定,你有一个没有增加价值的类。更糟糕的是,您切断了重要的可能性,如WHERE子句,或限制返回的列。在礼貌的社会中,从两个连接的表中请求所有行中的所有列都被认为是有些不可思议的!
故事的道德,不要尝试写一个会做任何事情的查询。编写更多,更小的查询,只需在需要时就可以恢复所需内容。