I have a table of Widgets with columns "Name" and "Count"
The "Count" field contains count of Posts each Widget would show:
Name | Count --------------------- RecentNews | 6 SpecialNews | 5 NewsGallery | 10
The second table associated with Widgets Table and Posts Table :
PostID | WidgetID ------------------ 100 | 6 101 | 5 102 | 10
For more performance, I just fetch last needed posts for each Widget by this query:
var postInWidgets = db.PostWidgets
.GroupBy(pw => pw.WidgetID)
.SelectMany(g => g.OrderByDescending(p => p.Post.DateCreated).Take(500))
.ToList();
and then get posts in each widget :
var postsInGalery = postInWidgets
.Where(wid => wid.WidgetID == 1).Take(6)
.ToList();
var postsInSpecialNews=postInWidgets
.Where(wid => wid.WidgetID == 2).Take(5)
.ToList();
var postsInRecentNews=postInWidgets
.Where(wid => wid.WidgetID == 5).Take(10)
.ToList();
and in each Widget Partial View :
foreach(var p in Model.PostsInRecentNews)
{
<li>@Html.ActionLink(p.Post.Title,"Index","Home")</li>
}
My Question : How to Set the int value of Take(count) Dynamically for each widget instead of Take(6) , Take(5) , Take(10) ...
I think I need to use TakeWhile() instead the Take()
Thanks for any assistance...
It sounds like you just need to fetch the counts first (you may want to cache them):
var counts = db.Counts.ToDictionary<string, int>(c => c.Name, c => c.Count);
Then:
var postsInGallery = postInWidgets
.Where(wid => wid.WidgetID == 1)
.Take(counts["NewsGallery"])
.ToList();
var postsInSpecialNews = postInWidgets
.Where(wid => wid.WidgetID == 2)
.Take(counts["SpecialNews"])
.ToList();
var postsInRecentNews = postInWidgets
.Where(wid => wid.WidgetID == 5)
.Take(counts["RecentNews"])
.ToList();
You could potentially use an enum instead of a string, to avoid the use of easily-typoed string constants. If the enum had a value of the related widget ID, you could wrap that up in a single method:
List<Widget> GetWidgets(WidgetType widgetType)
{
return postInWidgets.Where(wid => wid.WidgetID == (int) widgetType)
.Take(counts[widgetType])
.ToList();
}
Then call it as:
var postsInGallery = GetWidgets(WidgetType.NewsGallery);
var postsInSpecialNews = GetWidgets(WidgetType.SpecialNews);
var postInRecentNews = GetWidgets(WidgetType.RecentNews);
(This assumes counts
is a field somewhere, of course - adjust as per your requirements.)
See more on this question at Stackoverflow