HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Longer LINQ Chaining

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
longerlinqchaining

Problem

Anyone have ideas on how to improve this code at all?

string user = User.Identity.GetUserId();

        IQueryable t =
            db.Articles.Include(a => a.Categories)
                .Include(b => b.Shared)
                .Where(s => s.Private & s.createdby == User.Identity.Name);
        IQueryable q = db.Articles.Include(a => a.Shared).Where(s => s.Shared.Any(x => x.User == user));
        IQueryable art = t.Concat(q);
        IQueryable cat = db.Categories.Where(x => art.Any(c => c.categoryID == x.Id));


Especially looking to see if anyone has a fun way of putting all this into 1 query.

Solution

The first and most obvious improvement would be better variable naming:

IQueryable privateArticlesCreatedByUser =
    db.Articles.Include(article => article.Categories)
        .Include(article => article.Shared)
        .Where(article => article.Private && article.createdby == User.Identity.Name);

IQueryable articlesSharedWithUser = 
    db.Articles.Include(article => article.Shared)
        .Where(sharedArticle => sharedArticle.Shared.Any(shareRecipient => shareRecipient.User == user));

IQueryable articlesCreatedByOrSharedWithUser = privateArticlesCreatedByUser.Concat(articlesSharedWithUser);

IQueryable categories = db.Categories
    .Where(category => articlesCreatedByOrSharedWithUser.Any(articleCategory => articleCategory.categoryID == category.Id));


Obviously these names may not perfectly align with what the data means (as they're basically educated guesses on my part), but already they're a lot easier for somebody else to understand.

I also changed your & to an &&, since it then saves an equality check sometimes.

I also notice that you are including shared articles occurs twice. This might be too trivial an improvement and it's debatable if it will improve readability at all, but you could try this:

var sharedArticles = db.Articles.Include(article => article.Shared);

IQueryable privateArticlesCreatedByUser =
    sharedArticles.Include(article => article.Categories)
        .Where(article => article.Private && article.createdby == User.Identity.Name);

IQueryable articlesSharedWithUser = sharedArticles
        .Where(sharedArticle => sharedArticle.Shared.Any(shareRecipient => shareRecipient.User == user));

IQueryable articlesCreatedByOrSharedWithUser = privateArticlesCreatedByUser.Concat(articlesSharedWithUser);

IQueryable categories = db.Categories
    .Where(category => articlesCreatedByOrSharedWithUser.Any(articleCategory => articleCategory.categoryID == category.Id));

Code Snippets

IQueryable<Article> privateArticlesCreatedByUser =
    db.Articles.Include(article => article.Categories)
        .Include(article => article.Shared)
        .Where(article => article.Private && article.createdby == User.Identity.Name);

IQueryable<Article> articlesSharedWithUser = 
    db.Articles.Include(article => article.Shared)
        .Where(sharedArticle => sharedArticle.Shared.Any(shareRecipient => shareRecipient.User == user));

IQueryable<Article> articlesCreatedByOrSharedWithUser = privateArticlesCreatedByUser.Concat(articlesSharedWithUser);

IQueryable<Category> categories = db.Categories
    .Where(category => articlesCreatedByOrSharedWithUser.Any(articleCategory => articleCategory.categoryID == category.Id));
var sharedArticles = db.Articles.Include(article => article.Shared);

IQueryable<Article> privateArticlesCreatedByUser =
    sharedArticles.Include(article => article.Categories)
        .Where(article => article.Private && article.createdby == User.Identity.Name);

IQueryable<Article> articlesSharedWithUser = sharedArticles
        .Where(sharedArticle => sharedArticle.Shared.Any(shareRecipient => shareRecipient.User == user));

IQueryable<Article> articlesCreatedByOrSharedWithUser = privateArticlesCreatedByUser.Concat(articlesSharedWithUser);

IQueryable<Category> categories = db.Categories
    .Where(category => articlesCreatedByOrSharedWithUser.Any(articleCategory => articleCategory.categoryID == category.Id));

Context

StackExchange Code Review Q#64238, answer score: 5

Revisions (0)

No revisions yet.