tags:

views:

24

answers:

1

I'm using ASP.NET MVC, SQL Server 2008 and Forms Authentication. Suppose I am building a question-answer site like SO.

Here is the issue I am running into:

Users can view almost all the questions when not logged in, like they can on SO. Question-fetching query etc is almost written.

Now, if a user is logged in, he should also be able to tell whether he has already voted or "favorited" this question, like on SO.

  1. Do I go back and rewrite all my queries to include userIdInt parameter even when the user is anonymous just to know this information?
  2. Or when a user logs in, I store what all he has voted on and keep track of that throughout his session?

Both seem cumbersome, but 1) seems more efficient at least. Anybody know how SO does this or more efficient way?

I think it doesn't keep track of whether the user has voted, but it does seem to keep track of whether the user has "favorited" that question.

+2  A: 

You could use multiple interfaces, one for anonymous access, and one for authenticated access, and perform different queries for each:

http://en.wikipedia.org/wiki/Interface_segregation_principle

// Just example code - not asp.net-mvc
interface IAnonymousReader
{
    IEnumerable<Answer> GetAnswers(int page, int countPerPage);
}

interface IAuthenticatedReader
{
    IEnumerable<AuthenticatedAnswer> GetAnswers(int page, int countPerPage,
        int userId);
    // An alternative here is to get userId from concrete class, and pass in ctor
}

This would require that you write multiple queries, or that you get back data that you just throw away. You can avoid code duplication by constructing your query programatically. You could avoid writing the queries to begin with by using ORM.

As for the data, you could normalize the data, so that voting information is in a separate table, but still bound to the answer. When you're doing the query for anonymous users, simply don't join/query that table.

Merlyn Morgan-Graham
yes, the data is normalized. But, basically you're asking me to write two versions of the fetch query though. Do I have to use interface?
progtick
@progtick: No you don't have to use interfaces. Having multiple presentations of the same underlying data is considered a strong design principal. Whether those are classes, abstract classes, interfaces, webservice interfaces, etc are all implementation details. Why the aversion to multiple queries? Is the code (or code duplication) really that big? There are techniques you can use if you really can't stand the code duplication (for example, constructing the query string programatically), and you can avoid writing the queries themselves by using an ORM layer.
Merlyn Morgan-Graham
It's like I have 7-8 queries to fetch questions and now I would have to go back and write 7-8 more queries.. but that's okay I guess
progtick
@progtick: How many of those queries would have to change, and how many would be identical? You could place the string for those queries in a common area, so you only have to write the duplicate queries once. If there are duplicated parts of large strings, then you can split up the string and concatenate them together, or if the queries are nested, build functions to wrap one query string with an outer query.
Merlyn Morgan-Graham
@progtick: If the problem is really how to avoid duplicating the queries, can you place some (stripped down, revised so as not to expose your private data) version of the queries in the question, so we can help you with *that* problem. Or you could make a second question.
Merlyn Morgan-Graham