2011-10-10 38 views
0

我正在构建基于ASP.NET MVC 3.0的应用程序,并在MVC WebGrid中显示数据。ASP.NET MVC3-通过分页概念改进性能,我需要一个例子吗?

我正在使用LINQ从实体获取记录到EntityViewModel。在这样做时,我必须将记录从实体转换为EntityViewModel。

我有30K记录显示在网格中,每个记录都有3个标记,它必须去3个其他表并且比较记录的存在和paint与true或false并显示相同的格。

我一次显示10条记录,但是当我获取所有记录并存储在我的应用程序中时,它非常慢。

分页已到位(我的意思是说 - 只有10条记录正在Web网格中显示),但所有记录正在加载到应用程序,这需要15-20秒。我已经检查了处理器花费的时间。它发生在绘画的地方(每个记录都与其他3张表进行比较)。

我已经将LINQ查询转换为SQL,我可以看到我的SQL查询在2秒内得到执行。通过这个,我可以强烈地说,我不想花时间在SQL索引上,因为SQL查询的速度足够好。

我有两个选择来实现 1)缓存为MVC 2)寻呼(我应该只得到前10条记录)。

我想用寻呼技术来提高性能。

现在我的问题是如何将数字10(没有记录的服务方法)传递给它,以便它只带来十条记录。还有,点击下一页时如何获得下10条记录。

我会发布代码,但我不能这样做,因为它有一些敏感数据。

任何示例如何解决这种情况,非常感谢。

+1

你需要发布某种代码才能得到真正的答案。如果您担心泄露敏感信息,请更改变量和列名称。 – Dave

回答

-1

就我个人而言,我会创建一个自定义存储过程来做到这一点,然后通过Linq调用它到SQL。例如

CREATE PROCEDURE [dbo].[SearchData] 
(
@SearchStr NVARCHAR(50), 
@Page int = 1, 
@RecsPerPage int = 50, 
@rc int OUTPUT 
) 
AS 
SET NOCOUNT ON 
SET FMTONLY OFF 

DECLARE @TempFound TABLE 
(
UID int IDENTITY NOT NULL, 
PersonId UNIQUEIDENTIFIER 
) 

INSERT INTO @TempFound 
(
PersonId 
) 
SELECT PersonId FROM People WHERE Surname Like '%' + SearchStr + '%' 

SET @rc = @@ROWCOUNT 

-- Calculate the final offset for paging -- 
DECLARE @FirstRec int, @LastRec int 
SELECT @FirstRec = (@Page - 1) * @RecsPerPage 
SELECT @LastRec = (@Page * @RecsPerPage + 1) 


-- Final select -- 
SELECT p.* FROM People p INNER JOIN @TempFound tf 
ON p.PersonId = tf.PersonId 
WHERE (tf.UID > @FirstRec) AND (tf.UID < @LastRec) 

@rc参数是找到的记录总数。

显然,你必须把它模型,以自己的表,但它应该运行速度极快..

将其绑定到在LINQ to SQL对象,你就必须确保最终选择匹配字段它将被绑定到的对象的字段。

0

简单:

int page = 2; 
int pageSize = 10; 

var pagedStuff = query.Skip((page - 1) * pageSize).Take(pageSize); 

你应该永远,永远,永远是限行的,你从数据库中获取的量。无界的读取会终止应用程序。 30k变成300k,然后你只是摧毁你的SQL服务器。

0

Jfar在.Skip和.Take的正确轨道上。 Linq2Sql引擎(以及大多数实体框架)会将其转换为SQL,以返回有限的结果集。但是,这并不妨碍缓存结果。我也建议这样做。那最快的旅行到SQL Server是你不必采取的。 :)我做这样的事情在我的控制器方法处理分页或非分页的结果和缓存无论从SQL回来:

[AcceptVerbs("GET")] 
    [OutputCache(Duration = 360, VaryByParam = "*")] 
    public ActionResult GetRecords(int? page, int? items) 
    { 
     int limit = items ?? defaultItemsPerPage; 
     int pageNum = page ?? 0; 
     if (pageNum <= 0) { pageNum = 1; } 
     ViewBag.Paged = (page != null); 

     var records = null; 
     if (page != null) 
     { 
      records = myEntities.Skip((pageNum - 1) * limit).Take(limit).ToList(); 
     } 
     else 
     { 
      records = myEntities.ToList(); 
     } 
     return View("GetRecords", records); 
    } 

如果没有PARAMS调用它,你设置整个结果(/ GetRecords )。调用它会得到限制集(/ GetRecords?page = 3 & items = 25)。

您可以通过添加.Contains和.StartsWith功能进一步扩展此方法。

如果您决定使用自定义存储过程路由,我建议使用“TOP”和“ROW_NUMBER”来限制结果而不是临时表。