How to perform addition in a Linq query - c#

My query is like
var query = dbContext.table1.join(dbcontext.table2,i=>i.table1.id,j=>j.table2.id,
(i,j)=>new {
name = i.name,
hours = (new decimal?[]{ j.day1,j.day2,j.day3}.Sum()),
total = ???????
}).ToArray();
In the hours field I am getting the values of individual user's working hours for three days. In the "total" field I want to display the sum of all users' "hours" values.
Can you tell me how to get the "total" value?

var total = query.Sum(x => x.hours);
Since this total is for all rows in the result set, you do not want one value for each row, but one value representing the aggregate of the entire array.

Related

How to fetch the whole last row for the end of each month

I'm trying to access the last row of each month using LINQ and lambda expressions however I'm not sure how to do it.
I've got as far as a grouping but the issue is I don't think it contains all the data in the row.
var tonerPrinterList = _tonerPrinterRepo.GetTonerPrinterForDevice(printerId, starDate, endDate, color).GroupBy(tp => new {tp.timestamp.Year, tp.timestamp.Month});
The data structure that is produced by GetTonerPrinterForDevice contains more columns than the timestamp for example nominalCoverage and printerID which I need all these columns
I believe this should work.
You first order by dates, then you group by month, then you select the last of each group.
var tonerPrinterList = _tonerPrinterRepo.GetTonerPrinterForDevice(printerId, starDate, endDate, color)
.OrderBy(tp => tp.timestamp)
.GroupBy(tp => new {tp.timestamp.Year, tp.timestamp.Month})
.Select(group => group.LastOrDefault());

How to optimize C# mongodb query on large datadases?

I have a database table having 100 million records. Screen Shot is taken from Robomongo
Table Schema: There are 100 million records
When I run the following code. I get results, but It takes around 1 minute to get completed. I need to optimize the query to get results faster. What I have done till now is here. Please tell me the way forward to achieve the optimized result.
var collection = _database.GetCollection<BsonDocument>("FloatTable1");
var sw = Stopwatch.StartNew();
var builder = Builders<BsonDocument>.Filter;
int min = Convert.ToInt32(textBox13.Text); //3
int max = Convert.ToInt32(textBox14.Text); //150
var filt = builder.Gt("Value", min) & builder.Lt("Value", max);
var list = collection.Find(filt);
sw.Stop();
TimeSpan time = sw.Elapsed;
Console.WriteLine("Time to Fetch Record: " + time.ToString());
var sw1 = Stopwatch.StartNew();
var list1 = list.ToList();
sw1.Stop();
TimeSpan time1 = sw1.Elapsed;
Console.WriteLine("Time to Convert var to List: " + time1.ToString());
Console.WriteLine("Total Count in List: " + list1.Count.ToString());
Out Put is:
Time to Fetch Record: 00:00:00.0059207
Time to Convert var to List: 00:01:00.7209163
Total Count in List: 1003154
I have few question related to the given code.
When line collection.Find(filt) executes, does it fetch filtered record from the database OR Just creating filter?
var list1 = list.ToList(); takes 1 minute to execute, is it only converting from var to list OR First fetching data than converting?
How to achieve this query and result in least possible time. Please Help.
When line collection.Find(filt) executes, does it fetch filtered
record from the database OR Just creating filter?
It is just creating the filter.
var list1 = list.ToList(); takes 1 minute to execute, is it only
converting from var to list OR First fetching data than converting?
It is fetching the data and converting.
How to achieve this query and result in least possible time. Please Help.
The fetch / filtering on the database is eating your time. The easiest way to speed it up would be creating an index on the column you are filtering.
Everything else would need some more effort or database technologies, like creating a column which more roughly presents your date (e.g. grouped by day) and indexing this one, or creating something like table sections grouped by a given timespan (I'm not a DB-Admin and don't know the proper terms for this, but I remember somebody doing it on a database with billions of records ;) )

Obtain all records received within last six months

New to Linq to Entity, trying to get all records received within the last six months. I have spent the last several hours trying to get this to work. Any assistance would be greatly appreciated. When I call the 'limit' variable it is being assigned the date 01/01/0001. Any assistance would be appreciated. It works if I comment out the 'where' clause; however, I need it to be sorted by only the last six months.
Thanks in advance.
JobSeekersEntities context = new JobSeekersEntities();
var limit = DateTime.Today.AddMonths(-6);
var query = from c in context.Applications
where c.received > limit
orderby c.received descending
select new { c.firstName, c.middleName, c.lastName, c.street, c.city, c.state, c.zip, c.position };
var results = query.Take(25).ToList();
applicationDataGrid.DataContext = results;
If you stop the debugger at the line "var limit = " you will get that value. You need to press F10 to step over that code then look at value, it will be correct. Have to let that line run so that limit gets assigned. Var in this case is DateTime, which is a value type so it has a default value. I could see this being misleading.

Linq Objects Group By & Sum

I have a datatable with a column "No" and "Total" column. I'd like to bring back the sum of the "Total" column for each "No". I've tried the below, but I'm getting several errors as I'm struggling with the syntax.
var Values =
(from data in DtSet.Tables["tblDetails"].AsEnumerable()
group data by data.Field<"No">
select new
{
name_1 = data.Field<double>("No"),
name_2 = data.Field<double>("Total"),
}
);
This will give you sum of Total fields in name_2 property, and grouping No in name_1 property (I think you need better naming here)
var Values = from row in DtSet.Tables["tblDetails"].AsEnumerable()
group row by row.Field<double>("No") into g
select new
{
name_1 = g.Key,
name_2 = g.Sum(r => r.Field<double>("Total"))
};
Consider about names No and TotalSum instead.
You start using linq, but good old DataTable has it's own way:
var total = DtSet.Tables["tblDetails"].Compute("sum(Total)", "No = x");
I have to leave it with the x in it, because I don't know the values of the "No" column. The part "No = x" is a filter. If it is null or an empty string all rows will be used in the computation.

LinqToExcel: How do I exclude certain rows?

I've been struggling with this for a few days now and I'm stumped. I'm hoping that someone can provide an alternate suggestion.
Basically, I'm reading data from excel using LinqToExcel. But I want to exclude all rows with a "Rating" of "NR". Here's a sample of my data:
CompanyName Rating SalesMan
Apple 2 Steve
Google NR Steve
Microsoft 3 John
Dell 1 Steve
Pepsi 3 John
I just want to find all companies that belong to Steve but doesn't have a rating of "NR". My final list should be:
CompanyName SalesMan
Apple Steve
Dell Steve
I've tried the following code but it doesn't work:
1)
var masterList = masterDataXL.Worksheet("data_all").Where(d => !d["Rating"].Equals("NR"));
2)
var masterList = masterDataXL.Worksheet("data_all")
.Where(m =>
!m["Rating"].Equals("NR")
&&
m["SalesMan"].ToString().Contains(resAnLastName)) // check for last name
.Select(m => new ResAnTicksDataClass
{
Company = m["CompanyName"],
Rating = m["Rating"],
Seller = m["SalesMan"]
}).AsEnumerable();
3) Created a property for Rating and did the following:
var masterList = masterDataXL.Worksheet("data_all")
.Where(m =>
m["Analyst"].ToString().Contains(resAnLastName)) // check for last name
.Select(m => new ResAnTicksDataClass
{
Company = m["CompanyName"],
Rating = m["Rating"],
Seller = m["SalesMan"]
}).AsEnumerable();
var dataList = (from m in masterList
where m.Rating != "NR"
select new ResAnTicksDataClass
{
ResAnName = m.ResAnName,
DescrTick = m.DescrTick
}).AsEnumerable();
I'm open to any other suggestions that you might have because I'm completely stumped. Thank you so much in advance.
I suggest you select the 'Rating' column in your Excel file and do a search & replace on the selection (CHange 'NR' to '0') and then filter. Should help using a single data type.
As phoog said, converting Excel files into a table, that table will need to specify each column's type. To do so, it'll look only the 10 first rows of your Excel file. So if your file doesn't have a 'NR' value in the first 10 rows, it will set the column type to INT, and therefore fail to convert the value 'NR'.
A simple trick to fix this is to add a row to your Excel file, just before your first data row, with the data using the datatype you want to use.
As an example, if a column is using text values and sometimes the text is using over 255 caracters, make sure the first 10 rows have at least 1 text value using 256 caracters. Else, once it creates the table, the column will be set to VARCHAR(255) instead of VARCHAR(MAX) and then crash while converting texts longer than 255 caracters.
Conclusion: always make sure the first 10 rows are using the right type and size to fit all the rows of your Excel file!
In you first sample you should change this:
d => !d["Rating"].Equals("NR")
to this:
d => d["Rating"] != "NR"
It could also be written in a cleaner way:
var masterList =
from d in masterDataXL.Worksheet("data_all")
where d["Rating"] != "NR"
select d;

Categories