6

我看到了 Dapper 的出色性能以及如何使用它的一些示例。

我想知道是否可以使用它来提供 IQueryable 数据并使用 ODATA 将其与 UI 层集成以将数据传输到 UI(如网格、列表等)。

有什么方法可以返回 Dapper 对象 AsQueryable 而不是 IEnumerable 以使用 ODATA 进行查询?

4

3 回答 3

8

不,不是。好吧,如果你真的想要的话,你可以用 .AsQueryable() 包装任何序列,但它只是使用 LINQ-to-Objects。Dapper 故意简单;它试图做的很少,但它确实试图做的是:它做得很好(即使我自己这么说)。正确的 IQueryable 接口与 dapper 完全相反...

于 2012-07-28T20:03:04.803 回答
4

我最近发现自己处于这种情况,我想将 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;
    }
于 2016-08-25T12:17:40.233 回答
1

要将 Dapper 与 OData 一起使用,您必须截取Get(ODataQueryOptions<SpotView> queryOptions)参数,对其进行解析,并从中创建 Dapper 的 where 子句。您还需要考虑您在 WebApiConfig.cs 中的任何其他 OData 设置

config.AddODataQueryFilter(new EnableQueryAttribute()
{
...
});

但是,您也可以将 MySqlConnection 与 EF 一起使用,并且您不必通过上述解析重新发明轮子。但是,如果 Dapper 的性能比使用像 EF 这样的完整 ORM 更重要,那么这是你的决定,因为它已经内置了不同的执行。

于 2016-04-27T23:21:00.200 回答