raklos
raklos

Reputation: 28545

How to cache specific parts of the page with ASP.NET MVC?

I'm making a "reputation" type feature on my site similar to stack overflow. I want to display their points on by their name in the header.

I don't want to have to do a db call just for this every time they move to another page.

Can anyone suggest a nice way to implement this?

Upvotes: 0

Views: 927

Answers (3)

frennky
frennky

Reputation: 13924

If it's only a small part of part of page that needs to be cached, you could use child action to render that part, and cache it. Example: http://www.asp.net/learn/whitepapers/mvc3-release-notes#_Toc276711791

Upvotes: 0

Shiv Kumar
Shiv Kumar

Reputation: 9799

Don't make a db call just for this but get the data from the database while you're getting everything else.

Follow the principle of One Request Response cycle, one database call. It's really just a matter of joining in the other tables in your query.

For instance, if you look at a page that has a question and a bunch of answers. You know the "user" of the original question and you know the "user" of each of the answers and comments. So while you're getting the information also join in the pertinent information of each of the users. It's really just joining in additional tables and you can effectively get all of the data you require in one database call.

When you make a call to a database (like MSSQL server) you can get back multiple resultsets in one call, so you're also not limited to a single result set.

Edit:

Here is a sample Stored procedure (or just SQL statements) that results in 5 result sets in one database call.

ALTER PROCEDURE [dbo].[GetPostWithSlug]
@PostSlug varchar(80)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @PostId int;

    SELECT @PostId = PostId
    FROM dbo.Post
    WHERE PostSlug = @PostSlug

    SELECT      PostId, PostDate, PostSlug, dbo.[User].UserFirstName + ' ' + dbo.[User].UserLastName AS PostedBy, PostTitle, PostText, PostIsPublished, PostIsPublic, PostTitleImg, PostUpdatedDate, dbo.[User].UserWebsite AS AuthorWebsite
    FROM        dbo.Post
                INNER JOIN
                    dbo.[User]
                        ON dbo.[User].UserId = dbo.Post.UserId

    WHERE       PostId = @PostId

    /* SubCategories for Post */
    SELECT   dbo.PostSubCategory.PostId, dbo.Category.CategoryId, dbo.SubCategory.SubCategoryId, dbo.Category.CategoryDescription, dbo.SubCategory.SubCategoryDescription
    FROM     dbo.Category
             INNER JOIN
                dbo.SubCategory ON dbo.Category.CategoryId = dbo.SubCategory.CategoryId
             INNER JOIN
                dbo.PostSubCategory ON dbo.SubCategory.SubCategoryId = dbo.PostSubCategory.SubCategoryId
             INNER JOIN
                dbo.Post ON dbo.Post.PostId = dbo.PostSubCategory.PostId
    WHERE   dbo.Post.PostId = @PostId
    ORDER BY dbo.PostSubCategory.PostId

    /* Tags for Post */
    SELECT  dbo.PostTag.PostId, dbo.Tag.TagId, dbo.Tag.TagDescription
    FROM    dbo.PostTag
            INNER JOIN
                dbo.Tag ON dbo.Tag.TagId = dbo.PostTag.TagId
            INNER JOIN 
                dbo.Post ON dbo.Post.PostId = dbo.PostTag.PostId
    WHERE   dbo.Post.PostId = @PostId           
    ORDER BY dbo.PostTag.PostId, dbo.Tag.TagDescription

    /* Custom Groups for Post */
    SELECT dbo.PostCustomGroup.PostId, dbo.CustomGroupHeader.CustomGroupHeaderId, dbo.CustomGroup.CustomGroupId
    FROM dbo.CustomGroup
        INNER JOIN
            dbo.CustomGroupHeader ON dbo.CustomGroupHeader.CustomGroupHeaderId = dbo.CustomGroup.CustomGroupHeaderId
        INNER JOIN
            dbo.PostCustomGroup ON dbo.PostCustomGroup.CustomGroupId = dbo.CustomGroup.CustomGroupId
    WHERE   dbo.PostCustomGroup.PostId = @PostId


    EXEC GetCommentsForPost @PostId
END

In C# code, your DbDataReader will hold multiple result sets and these can be got by calling NextResult(). Or if you're filling a DataSet you can simply use the Fill method of a adapter.

I use this technique on my blog Matlus - Internet Technology and Software Engineering and you can see how fast (responsive) the site is. The same technique is used on ExposureRoom which is a public social networking website that has a huge amount of traffic.

Upvotes: 3

John Farrell
John Farrell

Reputation: 24754

You're looking for some way to do donut hole caching:

https://stackoverflow.com/search?q=[asp.net-mvc]+donut+hole+caching

Upvotes: 1

Related Questions