我想使用[DataSourceRequest] DataSourceRequest request
和ToDataSourceResult
我已经使用LINQ和EF完成了数百次,但是,这个当前项目要求我们使用存储过程,由context.Database.SqlQuery
这种方法很好,除了我需要将参数传递到存储过程的情况,这会导致错误:
另一个SqlParameterCollection已经包含了SqlParameter。
我认为原因是剑道的ToDataSourceResult
也试图将SQL参数附加到data
对象,而C#并不喜欢。
我在网上看到的一些解决方案是调用.ToList()
,这确实有效,然而,它有点失败,因为它仍会查询所有结果。
var data = context.Database.SqlQuery<TicketVm>("usp_FleetRentedEquipments @analyst",
new SqlParameter("@analyst", analyst));
return data.ToDataSourceResult(request);
答案 0 :(得分:2)
在ToDataSourceResult方法中,该查询至少使用两次-一次调用Count(),一次提取数据。这将导致两次使用SQL参数集的错误。您可能只能这样做:
var data = context.Database.SqlQuery<TicketVm>($"usp_FleetRentedEquipments {analyst}");
return data.ToDataSourceResult(request);
要非常小心,“分析器”不是SQL注入。
答案 1 :(得分:1)
我刚刚这样做了(注意:我使用的是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
});
GridBinder
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
}