MVC4 ToList() show first few records - c#

I'm just learning how to use .net and mvc4 and I have a problem. I have no idea how to show only the first 5(or any number) rows in a table. This is how I'm currently sending my information to the view.
public ActionResult ActiveCampaigns()
{
var campaigns = db.ActiveCampaigns.ToList();
return View(campaigns);
}
Thanks :)
Update:
Thanks for the quick responses! So simple!
db.ActiveCampaigns.Take(5).ToList()
I searched high and low and couldn't find this, my google-fu must be off. Thanks again!

The basic approach would be
var campaigns = db.ActiveCampaigns.Take(5).ToList();
But depending on what type of Context db is, this might fail. Skip() and Take() are not always available or allowed on all IEnumrable-derived interfaces. In that case read the error. Usually you can fix it in two ways:
var campaigns = db.ActiveCampaigns.ToList().Take(5); // expensive with many Campaigns
or, when you have a convenient sort-criterium:
var campaigns = db.ActiveCampaigns.OrderByDescending(c => c.Date).Take(5).ToList();

Enumerable.Take
public ActionResult ActiveCampaigns()
{
var campaigns = db.ActiveCampaigns.Take(5).ToList();
return View(campaigns);
}

I assume you're interested in paging, in which case, you'd need to use the Skip() method, also:
var campaigns = db.ActiveCampaigns.Skip(5).Take(5).ToList();
would get you page 2. Obviously, you're going to want to use a formula to handle which page to display:
var campaigns = db.ActiveCampaigns.Skip((page-1) * 5).Take(5).ToList();

Related

Need example for Azure Table query using ExecuteQuerySegmentedAsync

I'm simply trying to get all entities in an Azure Table matching a certain field name and can't seem to find any recent examples I can learn from.
Ultimately I want to display the results in an HTML table back to my view so I was thinking a List<ActivityModel> would make sense. Either that or an IEnumerable since I don't need to change any of the entities (just read). Either way I'm struggling with the basic concepts.
public async Task<List<ActivityModel>> GetActivitiesAsync(string domainName)
{
CloudTable cloudTable = TableConnection("NodeEvents");
TableQuery<ActivityModel> query = new TableQuery<ActivityModel>().Where(
TableQuery.GenerateFilterCondition("DomainName", QueryComparisons.Equal, domainName)
);
//tried many examples of continuation tokens/etc
}
The problem I'm running into is that all the latest SDK's use async calls with the use of a ContinuationToken and I can't seem to find any good examples. This seems like it should be a simple task. Any help is appreciated.
Tried to follow along here but the examples made reference to methods and operations not available anymore.
This worked for me. I wasn't able to find anything out there showing recent use of the Azure Tables SDK. Hopefully this works for others. Couple more things to note here:
The table has thousands of entities and I only wanted about 500 in total. While the code below sort of works, it needs some work on possibly the use of .Take(int). It's my understanding the "Take" method only throttles how many records are returned per query. Since I likely have a continuation token to deal with, setting it to something like 5 would only take 5 entities per request until the end of the list.
I added an index counter to break out in case we get more than 500 records however my testing is showing 2000+ records versus 5000+ without it so maybe this is a result of the async nature of the call?
public async Task<List<ActivityModel>> GetActivitiesAsync(string domainName)
{
List<ActivityModel> activities = new List<ActivityModel>();
CloudTable cloudTable = TableConnection("NodeEvents");
string filter = TableQuery.GenerateFilterCondition("DomainName", QueryComparisons.Equal, domainName);
TableContinuationToken continuationToken = null;
do
{
var result = await cloudTable.ExecuteQuerySegmentedAsync(new TableQuery<ActivityModel>().Where(filter), continuationToken);
continuationToken = result.ContinuationToken;
int index = 0;
if (result.Results != null)
{
foreach (ActivityModel entity in result.Results)
{
activities.Add(entity);
index++;
if (index == 500)
break;
}
}
} while (continuationToken != null);
return activities;
}

Trying to reference a query in a c# class

I'm trying to accomplish 2 things with the below snippet of code (from ApplicationDataService.lsml.cs in the server project of my Lightswitch 2013 solution).
partial void Query1_PreprocessQuery(ref IQueryable<CandidateBasic> query)
{
query = from item in query where item.CreatedBy == this.Application.User.Name select item;
}
partial void CandidateBasics_Validate(CandidateBasic entity, EntitySetValidationResultsBuilder results)
{
var newcandidateCount = this.DataWorkspace.ApplicationData.Details.GetChanges().AddedEntities.OfType<CandidateBasic>().Count();
var databasecandidateCount = this.CandidateBasics.GetQuery().Execute().Count();
const int maxcandidateCount = 1;
if (newcandidateCount + databasecandidateCount > maxcandidateCount)
{
results.AddEntityError("Error: you are only allowed to have one candidate record");
}
}
Firstly, I want to make sure each user can only see things that he has made. This, together with a preprocess query on the table in question, works perfectly.
The next bit is designed to make sure that each user can only create one record in a certain table. Unfortunately, it seems to be looking at the whole table, and not the query I made that shows only the user's own records.
How can I get that second bit of code to limit only the user's own records, and not the global table?
You're not actually calling that query though are you? Your query is called Query1 based on the code provided yet you don't seem to be calling it. I'd do something like:
int count = DataWorkspace.ApplicationData.Query1().Count();

Counts in Breeze.js

I have a complex query that returns item counts. If I run a query on the client, will it always return the objects, or is there a way to just return the item counts without sending the object array in the payload? I tried doing something like
var query = breeze.EntityQuery.from('Items').inlineCount(true);
but that still pulls all the records down. Any solutions?
I don't know if this exactly answers your question, but you would need to query the records in order to know how many there are (to my knowledge, there may be a more efficient way to tie Breeze directly into a SQL command that is way over my head) so you could do something like -
var query = breeze.EntityQuery.from('Items')
.take(0)
.inlineCount(true);
Edited the answer - this would return no objects and simply get the count.
The inlineCount answer already provided is absolutely correct.
Another alternative is to calculate the counts on the server and just send down the "summary". For example this server side controller method will return an array of two element objects to the client:
[HttpGet]
public Object CustomerCountsByCountry() {
return ContextProvider.Context.Customers.GroupBy(c => c.Country).Select(g => new {g.Key, Count = g.Count()});
}
This would be called via
EntityQuery.from("CustomerCountsByCountry")
.using(myEntityManager).execute()
.then(function(data) {
var results = data.results;
results.forEach(function(r) {
var country = r.Key;
var count = r.Count
});
});
var query = breeze.EntityQuery.from('Items')
.take(0)
.inlineCount(true);

Castle ActiveRecord - 2nd level cache - need explanation of this behaviour

I am just doing some experiments on Castle AR and 2nd level cache of NH. In the following two methods, I can see caching working fine but only for the repetition of the call of each. In other words if I call RetrieveByPrimaryKey twice for same PK, the object is found in cache. And if I call RetrieveAll twice, I see SQL issued only once.
But if I call RetrieveAll and then RetrieveByPrimaryKey with some PK, I see two SQL statements getting issued. My question is, Why AR does not look for that entity in cache first? Sure it would have found it there as a result of previous call to RetrieveAll.
public static T RetrieveByPrimaryKey(Guid id)
{
var res = default(T);
var findCriteria = DetachedCriteria.For<T>().SetCacheable(true);
var eqExpression = NHibernate.Criterion.Expression.Eq("Id", id);
findCriteria.Add(eqExpression);
var items = FindAll(findCriteria);
if (items != null && items.Length > 0)
res = items[0];
return res;
}
public static T[] RetrieveAll()
{
var findCriteria = DetachedCriteria.For<T>().SetCacheable(true);
var res = FindAll(findCriteria);
return res;
}
You're using caching on specific queries. that means that cache lookup is done in the following way:
search the cahce for results of a query with identical syntax AND the same parameters. If found- use cached results.
nHibernate (this has nothing to do with AR, by the way) doesn't know that logically, one query 'contains' the other. so this is why you're getting 2 db trips.
I would suggest using ISession.Get to retreive items by ID (it's the recommended method). I think (not tested it though) that Get can use items cached by other queries.
here's a nice blog post from ayende about it.

Retrieve only a particular number of child records

If I write
db.Topics.Include("ChildTopics")
then it gives all the child comments for that. But what I want is only the top two child topics ordered by "childtopic created date".
This is not possible to include only the first two via Include method.
In your case, you can do this :
var firstTwo = from topic in datacontext.Topics
select new { Topic= topic, ChildTopic= topic.ChildTopics.OrderBy(c => c.childtopic_created_date).Take(2) };
Include does an early load of all dependencies, but I am not aware of a way to apply restrictions on this implementation.
An alternate way would be to shape the results like:
var comments = db.Topics.Select(_x=>
new{
Topic = _x,
TopTwoChildTopics = _x.ChildTopics.Top(2)
});

Categories

Resources