我看到了 Dapper 的出色性能以及如何使用它的一些示例。
我想知道是否可以使用它来提供 IQueryable 数据并使用 ODATA 将其与 UI 层集成以将数据传输到 UI(如网格、列表等)。
有什么方法可以返回 Dapper 对象 AsQueryable 而不是 IEnumerable 以使用 ODATA 进行查询?
我看到了 Dapper 的出色性能以及如何使用它的一些示例。
我想知道是否可以使用它来提供 IQueryable 数据并使用 ODATA 将其与 UI 层集成以将数据传输到 UI(如网格、列表等)。
有什么方法可以返回 Dapper 对象 AsQueryable 而不是 IEnumerable 以使用 ODATA 进行查询?
不,不是。好吧,如果你真的想要的话,你可以用 .AsQueryable() 包装任何序列,但它只是使用 LINQ-to-Objects。Dapper 故意简单;它试图做的很少,但它确实试图做的是:它做得很好(即使我自己这么说)。正确的 IQueryable 接口与 dapper 完全相反...
我最近发现自己处于这种情况,我想将 Dapper 与 OData 一起使用,但我不想将 Entity Framework 用于 SQLite。
我的解决方案是为 ODataQueryOptions 创建一个扩展方法,所以我的控制器看起来像这样
public IHttpActionResult GetDevices(ODataQueryOptions<User> queryOptions)
{
var usersQuery = new UserQuery(page, perPage);
var users = usersQuery.Search(queryOptions.WhereClause(), queryOptions.OrderByClause());
return Ok<IEnumerable<User>>(users);
}
这看起来很简单,到目前为止它对我有用,所以我坚持使用它。就 odata 而言,我只需要限制用户可以过滤的内容
protected ODataValidationSettings _validationSettings =
new ODataValidationSettings
{
// These validation settings prevent anything except: (equals, and, or) filter and sorting
AllowedFunctions = AllowedFunctions.None,
AllowedLogicalOperators = AllowedLogicalOperators.Equal | AllowedLogicalOperators.And | AllowedLogicalOperators.Or | AllowedLogicalOperators.NotEqual,
AllowedArithmeticOperators = AllowedArithmeticOperators.None,
AllowedQueryOptions = AllowedQueryOptions.Filter | AllowedQueryOptions.OrderBy
};
这是扩展方法
public static string WhereClause(this ODataQueryOptions options)
{
string s = "";
if (options.Filter != null && options.Filter.FilterClause != null)
{
var node = options.Filter.FilterClause.Expression as BinaryOperatorNode;
s = getWhereClause(node);
}
return s;
}
private static string getWhereClause(BinaryOperatorNode node)
{
// PARSE FILTER CLAUSE
// Parsing a filter, e.g. /Users?$filter=Id eq '1' or Id eq '100'
var s = "";
if (node.Left is SingleValuePropertyAccessNode && node.Right is ConstantNode)
{
var property = node.Left as SingleValuePropertyAccessNode ?? node.Right as SingleValuePropertyAccessNode;
var constant = node.Left as ConstantNode ?? node.Right as ConstantNode;
if (property != null && property.Property != null && constant != null && constant.Value != null)
{
s += $" {property.Property.Name} {getStringValue(node.OperatorKind)} '{constant.Value}' ";
}
}
else
{
if (node.Left is BinaryOperatorNode)
s += getWhereClause(node.Left as BinaryOperatorNode);
if (node.Right is BinaryOperatorNode)
{
s += $" {getStringValue(node.OperatorKind)} ";
s += getWhereClause(node.Right as BinaryOperatorNode);
}
}
return s;
}
要将 Dapper 与 OData 一起使用,您必须截取Get(ODataQueryOptions<SpotView> queryOptions)
参数,对其进行解析,并从中创建 Dapper 的 where 子句。您还需要考虑您在 WebApiConfig.cs 中的任何其他 OData 设置
config.AddODataQueryFilter(new EnableQueryAttribute()
{
...
});
但是,您也可以将 MySqlConnection 与 EF 一起使用,并且您不必通过上述解析重新发明轮子。但是,如果 Dapper 的性能比使用像 EF 这样的完整 ORM 更重要,那么这是你的决定,因为它已经内置了不同的执行。