정렬을 호출하면 내 MVC3 WebGrid 정렬 동작을 재정 의하여 서버 측 정렬 및 데이터 반환을 수행 할 내 컨트롤러를 호출하는 방법이 있습니까?ASP.NET MVC3 WebGrid - 사용자 지정 서버 측 정렬
도움 주셔서 감사합니다.
정렬을 호출하면 내 MVC3 WebGrid 정렬 동작을 재정 의하여 서버 측 정렬 및 데이터 반환을 수행 할 내 컨트롤러를 호출하는 방법이 있습니까?ASP.NET MVC3 WebGrid - 사용자 지정 서버 측 정렬
도움 주셔서 감사합니다.
레코드 수에 대한 정보와 함께 서버 측 정렬 된 데이터를 webgrid에 전달할 수 있습니다. http://msdn.microsoft.com/en-us/magazine/hh288075.aspx에는 유용한 연습이 있습니다. 나는 전달되는 데이터의 양을 최소화하기 위해 데이터베이스 레벨 정렬/필터링/페이징을하고있다. 나는 고객이 가지고있는 70,000 개의 모든 객체를 통과하면 1 페이지의 25를 볼 수 있기 때문에 내 웹 서버가 나를 사랑하지 않을 것이라고 생각합니다. 이것은 IEnumerable 컬렉션을 감싸는 매우 가벼운 뷰 모델을 제외하고는 필요한 모든 것입니다. 일부 추가 페이징 데이터가 있습니다.
웹 그리드는 쿼리 문자열 vars를 사용하여 수행 할 작업을 결정하기 때문에 get 메소드 양식을 사용해야합니다. 그리고 webgrid가 그것을 읽는 방법을 알고있는 방식으로 쿼리 문자열에 정렬 필드/방향을 포함시켜야합니다. 그래서 당신은 로컬 호스트/예/관리/일이 같은 URL을 끝낼 thingName = 하얏트 & 도시 = & 주 = TX & 나라 = & 종류 = 도시 & SORTDIR = ASC
컨트롤러 :
public ActionResult Index(string thingName, string city, string state, string country, int page = 1)
{
const int pageSize = 25;
int totalRecords = 0;
IEnumerable<Thing> things = ThingModel.GetPagedSortedLocationsForCustomer(customerId, sort, sortdir, out totalRecords, pageSize, page, thingName, city, state, country);
PagedThings viewModel = new PagedThings(pageSize, page, totalRecords, things);
return View(viewModel);
}
보기 :
@model ExampleCompany.Area.ViewModels.PagedThings
@{
using (Html.BeginForm("Index", "ThingaMaBob", System.Web.Mvc.FormMethod.Get))
{
<label for="ThingName">ThingName</label>@Html.TextBox("ThingName", "")
<label for="City">City</label>@Html.TextBox("City", "")
<label for="State">State</label>@Html.TextBox("State", "")
<label for="Country">Country</label>@Html.TextBox("Country", "")
<input type="submit" value="Filter" />
<br />
var grid = new WebGrid(canPage: true, rowsPerPage: Model.PageSize, canSort: true);
grid.Bind(Model.Things, rowCount: Model.TotalRows, autoSortAndPage: false);
grid.Pager(WebGridPagerModes.All);
@grid.GetHtml(htmlAttributes: new { id = "grid"},
columns: grid.Columns(
//ommitted
grid.Column("thingName", "Thing"),
));
Html.Hidden(grid.SortFieldName, grid.SortColumn);
Html.Hidden(grid.SortDirectionFieldName, grid.SortDirection == SortDirection.Ascending ? "ASC" : "DESC");
}
모델 :
public static IEnumerable<Thing> GetPagedSortedThingsForCustomer(int customerid, String sortby, String sorttype, out int totalRecords, int pageSize, int pageIndex, string thingName, string city, string state, string country)
{
var tmp = new List<Thing>();
int total = 0;
dynamic dr = OurDBUtility.ReturnDR("ExampleProc_GetThingsSortedPaged", ConnectionInfo.ExampleConnection, customerid, sortby, sorttype, pageSize, pageIndex, thingName, city, state, country);
{
while (dr.Read())
{
var tmpThing = new Thing();
tmpThing.LoadFromDr(dr);
tmp.Add(tmpThing);
if (total == 0)
{
total = (int)dr["TOTAL_THINGS"];
}
}
}
totalRecords = total;
return tmp;
}
동적 SQL과
발동은 - 그래, 당신은 사용할 수 있습니다 또는 당신이 원하는 경우 다른 기술 Linq에-SQL-에,하지만 난 구식이야 : CTE와
CREATE PROCEDURE ExampleProc_GetThingsSortedPaged
(@CustomerId int
, @sortby nvarchar(60)
, @sorttype nvarchar(60)
, @pageSize int
, @pageIndex int
, @thingName nvarchar(255) = null
, @city nvarchar(30) = null
, @state nvarchar(30) = null
, @country char(2) = null
)
as
DECLARE @strSql nvarchar(3000)
--calculate paging rows
declare @startRow int, @endRow int
--e.g. if you have a page size of 10, page 1 = 1 - 10, page 2 = 11 -20
set @startRow = ((@pageIndex - 1) * @pageSize) + 1
set @endRow = @startRow + @pageSize - 1
if @thingName = ''
set @thingName = null
if @city = ''
set @city = null
if @state = ''
set @state = null
if @country = ''
set @country = null
--return total for webgrid, accounting for filter
declare @totalThings int
select @totalThings = COUNT(*)
from EXAMPLE_TABLE T with(nolock)
where CUSTOMER_ID = @CustomerId
AND (T.THING_NAME LIKE @thingName + '%' OR @thingName is null)
AND (T.CITY LIKE @city + '%' or @city is null)
AND (T.STATE LIKE @state + '%' or @state is null)
AND (T.COUNTRY = @country or @country is null)
DECLARE @ParameterDefinition AS NVARCHAR(200)
set @ParameterDefinition = '@totalThings int, @CustomerId INT, @startRow INT, @endRow INT, @thingName nvarchar(255), @city nvarchar(30), @state nvarchar(30), @country char(2)'
--When we need to do dynamic sql it is better to use paramterization, but you cannot do (ORDER BY @sortBy).
SET @strSql = N'SELECT * from
(
select ROW_NUMBER() OVER (ORDER BY T.' + @sortby + ' ' + @sorttype + ') as Row,
@totalThings [TOTAL_THINGS],
T.THING_ID, T.THING_NAME, T.ADDRESS, T.CITY, T.STATE,
T.ZIP_CODE, T.COUNTRY
FROM EXAMPLE_TABLE T
WHERE T.CUSTOMER_ID = @CustomerId
AND (T.THING_NAME LIKE @thingName + ''%'' OR @thingName is null)
AND (T.CITY LIKE @city + ''%'' or @city is null)
AND (T.STATE LIKE @state + ''%'' or @state is null)
AND (T.COUNTRY = @country or @country is null)
) paged
where Row between @startRow and @endRow
ORDER BY Row'
--print @strSql
EXECUTE sp_executesql @strSql, @ParameterDefinition, @totalThings, @CustomerId, @startRow, @endRow, @thingName, @city, @state, @country
GO
PROC :
CREATE PROCEDURE ExampleProc_GetThingsSortedPaged
(@CustomerID int
, @sortby nvarchar(60)
, @sorttype nvarchar(60)
, @pageSize int = 25
, @pageIndex int = 1
, @thingName nvarchar(255) = null
, @city varchar(30) = null
, @state nvarchar(30) = null
, @country char(2) = null
)
as
declare @startRow int
declare @endRow int
SET @startRow = ((@pageIndex - 1) * @pageSize) + 1;
SET @endRow = @startRow + @pageSize - 1;
set @sortby = replace(LOWER(@sortby), '_', '')
SET @sorttype = LOWER(@sorttype)
if @sorttype != 'asc' and @sorttype != 'desc'
begin
set @sorttype = 'asc'
end
;with cte_things as (
SELECT
CASE
WHEN @sortby ='country' AND @sorttype = 'asc' then row_number() over (order by C.COUNTRY_NAME ASC)
WHEN @sortby ='country' AND @sorttype = 'desc' then row_number() over (order by C.COUNTRY_NAME DESC)
WHEN @sortby ='state' AND @sorttype = 'asc' then row_number() over (order by STATE ASC)
WHEN @sortby ='state' AND @sorttype = 'desc' then row_number() over (order by STATE DESC)
WHEN @sortby ='city' AND @sorttype = 'asc' then row_number() over (order by CITY ASC)
WHEN @sortby ='city' AND @sorttype = 'desc' then row_number() over (order by CITY DESC)
WHEN @sortby ='thingname' AND @sorttype = 'desc' then row_number() over (order by THING_NAME DESC)
ELSE row_number() over (order by THING_NAME ASC)
END AS Row
,T.THING_ID, T.THING_NAME, T.THING_TYPE, T.ADDRESS, T.CITY, T.STATE
, T.ZIP_CODE, T.COUNTRY_CODE, C.COUNTRY_NAME, T.PHONE_NUMBER
, T.LATITUDE, T.LONGITUDE
FROM EXAMPLE_TABLE L
join COUNTRIES C
on C.COUNTRY_CODE = L.COUNTRY_CODE
where
T.CUSTOMER_ID = @CustomerId
and L.CITY = ISNULL(@city, CITY)
and L.STATE = ISNULL(@state, STATE)
and L.COUNTRY_CODE = ISNULL(@country, L.COUNTRY_CODE)
and L.THING_NAME = ISNULL(@thingName, THING_NAME)
)
, cte_total as (select COUNT(*) as TOTAL_THINGS from cte_things)
, cte_all as (select cte_things.*, cte_total.TOTAL_THINGS from cte_things cross join cte_total)
SELECT * FROM cte_all
where
Row >= @startRow
and Row <= @endRow
ORDER BY Row
GO
아하! 필자는 필터링 및 서버 측 페이징을 사용하여 WebGrid의 예를 찾고 있습니다. 고마워. – Carl
사람들이 "필터"텍스트 상자를 넣는 미친 예제를 계속보고 있습니다. 분명히 사용자는 데이터베이스 열 이름이나 모델 이름을 사용하여 필터에 입력하려고합니다. 그것은 나에게 매우 위험한 것처럼 보입니다. 어쨌든, 사소한 업데이트. 내가 역동적 인 SQL을 제거하고 .net에서 paramterized 쿼리를 만들려고합니다. 그래서시에서 필터링을하지 않을 때 City의 조건을 하드 코드 할 필요가 없습니다. 그리고 네, 당신은 동적 SQL에서 그것을 제거 할 수 있지만 @ parameterDefinition 다루기 까다 롭습니다. –
사용자에게 열 이름을 표시하는 것이 위험하고 우호적이지 않은 것처럼 보입니다! 하지만 너 거기 간다. DB 비트에 대해서는 Entity Framework Linq에서 엔티티에 시간을 투자하는 것이 좋습니다. 나는 너와 같은 옛 학교 다. 그래서 나는 설득했다. 그러나 나는 그것을 좋아한다. – Carl
아래 답변이 귀하가 찾고있는 것이라면 알려주십시오. –