Nesting sum with linq, int does not contain Sum - c#

The following nested line gives an error but I don't really understand what is wrong. I'm coding in C#. If I look at other examples this should do the trick but unfortunately it doesn't.
var PupilsAmount= entities.Reservation.AsEnumerable().Where(x => x.AmountOfAttendants= 2.Sum(x => x.PupilsAmount));
So I want to give the sum of the value PupilsAmount only for the records where the attendants amount = 2.
Thanks in advance!

The error message is because you're calling Sum on the value 2. Sum is an extension method that operates on IEnumerable<T> (e.g. some sort of collection), not on an int.
Based on your edit, what you're after is:
var PupilsAmount= entities.Reservation.AsEnumerable().Where(x=>x.AmountOfAttendants==2).Sum(x=>x.PupilsAmount);
What's happening in my modification is a two-stage process:
First, I filter the list using Where, to get only the records where AmountOfAttendants is equal to 2
Then, I sum PupilsAmount for the remaining records.

Related

IEnumerable.Select() returning unexpected results

I am querying Azure Table Storage using C#, which returns an IEnumerable. I am using .Select() to get two different attributes from my result but the count of each attribute is not correct. For example:
IEnumerable<SomeClass> results = table.ExecuteQuery(query);
IEnumerable<DateTime> dates = results.Select(x => x.Date);
IEnumerable<double> doubles = results.Select(x => x.Doubles);
Every result has a date and a double value (I have verified this), so the count of each of them should be exactly the same as each other and result but they come back differently. I might have 300k results, and then 299,997 dates and 300,003 doubles.
When I do something like:
results.ToList();
and then use .Select() I get the correct results. I am trying to avoid converting the records to a list first because it takes way too long. I also want to avoid using a for loop or a foreach loop because they also take far too long.
My question is: Is there a way to use .Select() on an IEnumerable and get accurate results? Or is there another way to do this which would be very fast?
NOTE: I am plotting this data on an xy graph and for about 300k records it takes about 1 minute 30 seconds. About 90% of that time is due to a foreach loop I had. If I convert to a list first it takes even longer to process. Using the .Select() on an IEnumerable is very fast but I need reliable results and the amount of x values has to be the same as y values.
Azure tables / SDK uses lazy enumerables. The actual http request to table service to retrieve the entities is not done when you call executequery but when you iterate over the returned Ienumerable results. That's one possibility why you see diff results as you iterate over the enumerable by select maybe the data on the table is changing?

Limit Number of Results being returned in a List from Linq

I'm using Linq/EF4.1 to pull some results from a database and would like to limit the results to the (X) most recent results. Where X is a number set by the user.
Is there a way to do this?
I'm currently passing them back as a List if this will help with limiting the result set. While I can limit this by looping until I hit X I'd just assume not pass the extra data around.
Just in case it is relevant...
C# MVC3 project running from a SQL Server database.
Use the Take function
int numberOfrecords=10; // read from user
listOfItems.OrderByDescending(x => x.CreatedDate).Take(numberOfrecords)
Assuming listOfItems is List of your entity objects and CreatedDate is a field which has the date created value (used here to do the Order by descending to get recent items).
Take() Function returns a specified number of contiguous elements from the start of a
sequence.
http://msdn.microsoft.com/en-us/library/bb503062.aspx
results = results.OrderByDescending(x=>x.Date).Take(10);
The OrderByDescending(...) will sort items by your date/time property (or w/e logic you want to use to get most recent) and Take(...) will limit to first x items (first being most recent, thanks to the ordering).
Edit: To return some rows not starting at the first row, use Skip():
results = results.OrderByDescending(x=>x.Date).Skip(50).Take(10);
Use Take(), before converting to a List. This way EF can optimize the query it creates and only return the data you need.

NHibernate - How do I use a sum project on paged results

I'm trying to use paging in conjunction with a sum projection to get a sum of the values in a column for just the page of results I'm interested in. I'm using .NET, C# and NHibernate 3.1
I have an ICriteria to start with which is related to all rows from the associated db table.
I'm then doing the following to get a version with the first page (say, 10 items out of 40):
ICriteria recordsCriteria = CriteriaTransformer.Clone(criteria);
recordsCriteria.SetFirstResult(0);
recordsCriteria.SetMaxResults(10);
I'm using this ICriteria for something else so I then create two further clones:
ICriteria totalAggCriteria = CriteriaTransformer.Clone(criteria);
ICriteria pageAggCriteria = CriteriaTransformer.Clone(recordsCriteria);
If I take a look inside these two new ones the first has 40 items in and the second has 10 - exactly what I want.
Let's say the objects coming back from the DB have a column called "ColA" and it's of type Int32.
From this, I want the sum of all 40 ColA values and the sum of the first 10 ColA values.
To get the sum of all 40 ColA values, I do the following:
totalAggCriteria.SetProjection(NHibernate.Criterion.Projections.Sum("ColA"));
var totalSum = totalAggCriteria.UniqueResult();
The value in totalSum is correct.
To get the sum of the first 10 ColA values, I'm trying the following:
pageAggCriteria.SetProjection(NHibernate.Criterion.Projections.Sum("ColA"));
vat pageSum = pageAddCriteria.UniqueResult();
However, this gives me the same value as the previous one - for all 40 ColA values.
I've also tried the following but it gives the same result:
pageAggCriteria.SetProjection(NHibernate.Criterion.Projections.Sum(column));
pageAggCriteria.SetFirstResult(firstResult.Value);
pageAggCriteria.SetMaxResults(pageSize.Value);
pageSum = pageAggCriteria.UniqueResult();
And also:
pageAggCriteria.SetFirstResult(firstResult.Value);
pageAggCriteria.SetMaxResults(pageSize.Value);
pageAggCriteria.SetProjection(NHibernate.Criterion.Projections.Sum(column));
pageSum = pageAggCriteria.UniqueResult();
Can anyone give an idea on where I'm going wrong and how I can actually get the sum of the ColA values in the first 10 results?
Thanks
Probably easiest to do that sum client side. The aggregate function is operating on the whole table. What you are trying to do is run the aggregate function against the paged result which I don't think is possible with NH.
In other words, you want select sum(colA) from (select top 10 ...) but that criteria will give you select top 10 sum(colA) from ...)

How to find max value in a column in a datarow[] ?

I have a simple problem but I just don't understand any of the examples I find here or in MSDN. (I'm still new to C# and all the datasets functions).
I have a datatable "tblRoom" which its columms are "building","apartment" and "room" and they're all ints and the table's primary keys (it's a weak entity of apartment (which is weak entity of building) without other properties/columns).
I also have DataRow[] roomCollection that selects a specific apartment in a building with this code:
roomCollection = dbDataSet.tblRoom.Select("building ='"+ b_int +
"' and apartment='"+ a_int + "'");
All this runs fine (I guess...).
Now I want to get max value of room from this apartment (the max room number in this apartment).
I've tried to no avail these codes:
DataRow dr = roomCollection.Max();
int maxi = roomCollection.Max();
I just don't get from the tooltip what am I suppose to write in the function. It throws exceptions on either no IEnumerable or Icomparable.
What do I need to write to get the max value (int) in the room column? Anyone knows a "[something] for dummies" that explains it to an idiot because I don't understand the meaning of the errors/tooltip of what am I suppose to write in the Max().
EDIT:
The tooltip suggest to enter these (shown relevants):
(this IEnumerable <DataRow> source):DataRow
(this IEnumerable <DataRow> source, Func<DataRow,int?> selector):int?
(this IEnumerable <DataRow> source, Func<DataRow,int> selector):int
I really don't get it :(
Thanks ahead,
Shay.
try
int roomno = roomCollection.Max (r => (int) r["room"]);
In this case you would want to pass the selector to Max() to properly identify the column you want to max..
int max = roomCollection.Max(dr => (int)dr["room"]);
Since roomCollection is an array of DataRows, DataRow dr = roomCollection.Max(); means select the maximum DataRow from roomCollection. But what does it mean for a DataRow to be greater than another DataRow? In general there isn't any useful comparison which is why .Max() fails on you.
Technically DataRow doesn't implement IComparable because there is on generic useful why to compare two DataRow's and tell which one is 'larger' or 'smaller'. However for integers there is since 2 is larger than 1.
What you need to do is pass a selector function to Max() to tell it what maximum value you are looking for. So as the other answers indication you need to use:
int max = roomCollection.Max(dr => (int)dr["room"]);
This says for each DataRow select the integer value for room and get the maximum room value.
The .Max() function is a part of the Linq (Language Integration Query) added in .NET 3.5. So you need to read up on that to better understand what's going on. I've found 101 Linq Samples to be useful since it shows examples for almost every thing you would want to do.

Linq operations against a List of Hashtables?

I'm working with a set of legacy DAO code that returns an IList, where each Hashtable represents the row of a dynamically executed SQL query. For example, the List might contain the following records/hashtables:
Hashtable1:
Key:Column15, Value:"Jack"
Key:Column16, Value:"Stevens"
Key:Column18, Value:"7/23/1973"
Key:Column25, Value:"Active"
Hashtable2:
Key:Column15, Value:"Melanie"
Key:Column16, Value:"Teal"
Key:Column18, Value:"null"
Key:Column25, Value:"Inactive"
Hashtable3:
Key:Column15, Value:"Henry"
Key:Column16, Value:"Black"
Key:Column18, Value:"3/16/1913"
Key:Column25, Value:"Active"
Use of a static type instead of a Hashtable is out of the question because the result of the query is unknown at run time; both the number of columns and the nature of those columns is completely dynamic.
I'd like to be able to perform Linq based operations on this data set (grouping, ordering etc), but I absolutely can't get my head around what the syntax might look like. As a simple example, let's say I want to sort the list by Column15 descending. The best syntax I've come up with is:
var rawGridData = (List<Hashtable>) _listDao.GetListGridContents(listID, null, null);
var sortedGridData = rawGridData.OrderBy(s => s.Keys.Cast<string>().Where(k => k == "Column15"));
However, this yields an exception when sortedGridData is enumerated: "At least one object must implement IComparable."
I've been struggling with this problem for days and am near my wit's end...please help!
This should get you started:
var sortedGridData = rawGridData.OrderBy(r => r["Column15"])
This maps each "record" to the value in "Column15" and then orders the resulting projection. This is easily generalizable.

Categories