【问题标题】:Server side kendo paging with stored procedures带有存储过程的服务器端剑道分页
【发布时间】:2015-11-20 23:52:10
【问题描述】:

我想使用[DataSourceRequest] DataSourceRequest requestToDataSourceResult 实现服务器端分页/排序/等

我已经使用 LINQ 和 EF 完成了数百次,但是,当前的项目要求我们使用存储过程,由 context.Database.SqlQuery 调用

这很好用,除非我还需要将参数传递到存储过程中,这会导致错误:

SqlParameter 已被另一个 SqlParameterCollection 包含。

我认为这是因为 Kendo 的 ToDataSourceResult 还试图将 SQL 参数附加到 C# 不喜欢的 data 对象。

我在网上看到的一些解决方案是调用.ToList(),这确实有效,但是,它有点失败,因为它仍然会查询所有结果。

var data = context.Database.SqlQuery<TicketVm>("usp_FleetRentedEquipments @analyst",
                                               new SqlParameter("@analyst", analyst));
return data.ToDataSourceResult(request);

【问题讨论】:

  • 我也遇到了同样的问题...你解决了吗?
  • 是的,我也需要这个答案

标签: sql-server asp.net-mvc kendo-ui kendo-grid


【解决方案1】:

在 ToDataSourceResult 方法中,查询至少使用了两次——一次是调用 Count(),一次是提取数据。这会导致使用 SQL 参数集两次的错误。您可能只能这样做:

var data = context.Database.SqlQuery<TicketVm>($"usp_FleetRentedEquipments {analyst}");
return data.ToDataSourceResult(request);

并且要非常小心,'analyst' 不是 SQL 注入。

【讨论】:

    【解决方案2】:

    我刚刚这样做了(注意:我使用的是 Dapper 和 EF)

    var gridBinder = new GridBinder(request);
    
    var filters = gridBinder.GetFilterDescriptor();
    
    var sorting = gridBinder.SortInfo.Member.HasValue() ? string.Format("{0} {1}", gridBinder.SortInfo.Member, gridBinder.SortInfo.Direction) : "";
    
    var p = new DynamicParameters();
    p.Add("@Page", gridBinder.PageNumber, DbType.Int32, ParameterDirection.Input);
    p.Add("@PageSize", gridBinder.PageSize, DbType.Int32, ParameterDirection.Input);
    p.Add("@Filter", filters);
    p.Add("@SortOrder", sorting);
    p.Add("@TotalRowCount", dbType: DbType.Int32, direction: ParameterDirection.Output);
    
    var data = _db.Connection().Query<IndexVm>("dbo.People_GetAll", p, commandType: System.Data.CommandType.StoredProcedure, transaction: _db.Database.CurrentTransaction.GetDbTransaction());
    
    gridBinder.RecordCount = data.FirstOrDefault().TotalRowCount;
    
    return Json(new DataSourceResult
    {
        Total = gridBinder.RecordCount,
        Data = data
    });
    

    网格绑定器

    public class GridBinder
    {
        public int PageNumber { get; set; } = 1;
    
        public int PageSize { get; set; } = 10;
    
        public int RecordCount { get; set; }
    
        public SortInfo SortInfo { get; set; } = new SortInfo() { Direction = SortDirection.Asc, Member = string.Empty };
    
        private readonly DataSourceRequest _command;
    
        public GridBinder(DataSourceRequest command)
        {
            _command = command;
            PageNumber = command.Page;
            PageSize = command.PageSize;
            GetSortDescriptor();
        }
    
        private void GetSortDescriptor()
        {
            foreach (SortDescriptor descriptor in _command.Sorts)
            {
                SortInfo.Member = descriptor.Member;
                SortInfo.Direction = descriptor.SortDirection == ListSortDirection.Ascending ? SortDirection.Asc : SortDirection.Desc;
            }
        }
    
        public string GetFilterDescriptor()
        {
            string filters = string.Empty;
            foreach (IFilterDescriptor filter in _command.Filters)
            {
                filters += ApplyFilter(filter);
            }
    
            return filters;
        }
    
        private static string ApplyFilter(IFilterDescriptor filter)
        {
            var filters = "";
            if (filter is CompositeFilterDescriptor)
            {
                filters += "(";
                var compositeFilterDescriptor = (CompositeFilterDescriptor)filter;
                foreach (IFilterDescriptor childFilter in compositeFilterDescriptor.FilterDescriptors)
                {
                    filters += ApplyFilter(childFilter);
                    filters += " " + compositeFilterDescriptor.LogicalOperator.ToString() + " ";
                }
            }
            else
            {
                string filterDescriptor = "{0} {1} {2}";
                var descriptor = (FilterDescriptor)filter;
                if (descriptor.Operator == FilterOperator.StartsWith)
                {
                    filterDescriptor = string.Format(filterDescriptor, descriptor.Member, "LIKE", "'" + descriptor.Value + "%'");
                }
                else if (descriptor.Operator == FilterOperator.EndsWith)
                {
                    filterDescriptor = string.Format(filterDescriptor, descriptor.Member, "LIKE", "'%" + descriptor.Value + "'");
                }
                else if (descriptor.Operator == FilterOperator.Contains)
                {
                    filterDescriptor = string.Format(filterDescriptor, descriptor.Member, "LIKE", "'%" + descriptor.Value + "%'");
                }
                else if (descriptor.Operator == FilterOperator.DoesNotContain)
                {
                    filterDescriptor = string.Format(filterDescriptor, descriptor.Member, "NOT LIKE", "'%" + descriptor.Value + "%'");
                }
                else if (descriptor.Operator == FilterOperator.IsEqualTo)
                {
                    filterDescriptor = string.Format(filterDescriptor, descriptor.Member, "=", "'" + descriptor.Value + "'");
                }
                else if (descriptor.Operator == FilterOperator.IsNotEqualTo)
                {
                    filterDescriptor = string.Format(filterDescriptor, descriptor.Member, "<>", "'" + descriptor.Value + "'");
                }
                else if (descriptor.Operator == FilterOperator.IsGreaterThan)
                {
                    filterDescriptor = string.Format(filterDescriptor, descriptor.Member, ">", "'" + descriptor.Value + "'");
                }
                else if (descriptor.Operator == FilterOperator.IsGreaterThanOrEqualTo)
                {
                    filterDescriptor = string.Format(filterDescriptor, descriptor.Member, ">=", "'" + descriptor.Value + "'");
                }
                else if (descriptor.Operator == FilterOperator.IsLessThan)
                {
                    filterDescriptor = string.Format(filterDescriptor, descriptor.Member, "<", "'" + descriptor.Value + "'");
                }
                else if (descriptor.Operator == FilterOperator.IsLessThanOrEqualTo)
                {
                    filterDescriptor = string.Format(filterDescriptor, descriptor.Member, "<=", "'" + descriptor.Value + "'");
                }
    
                filters = filterDescriptor;
            }
    
            filters = filters.EndsWith("And ") == true ? filters.Substring(0, filters.Length - 4) + ")" : filters;
            filters = filters.EndsWith("Or ") == true ? filters.Substring(0, filters.Length - 4) + ")" : filters;
    
            return filters;
        }
    }
    public class SortInfo
    {
        public string Member { get; set; }
        public SortDirection Direction { get; set; }
    }
    
    public enum SortDirection
    {
        Asc, Desc
    }
    

    【讨论】:

    • 什么是动态参数?
    • 可以改用普通的sql参数吗?
    • 你有没有想办法在没有第三方控制的情况下做到这一点?我不能用这个,因为它需要钱才能使用这个控件。
    • 如果您指的是 Dapper,那么它是免费的。如果需要,您可以使用标准 SqlParameters。
    猜你喜欢
    • 2013-07-08
    • 1970-01-01
    • 2023-03-16
    • 2011-11-05
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    相关资源
    最近更新 更多