How to get second and third rows using Entity Framework - c#

I need to get the first row of the location record in order to added time,
My query as follows,
private Location GetFirstRecord()
{
return clientContext.Lobbies.Where(location => location.FkBranchId == locationRecord.FkBranchId && !location.FkAppointmentId.HasValue && location.Status == 1 && location.IsActive).OrderBy(location => location.AddedTime).FirstOrDefault();
}
The above query works fine, now I need to get second, third, fourth.....10th row records from the location. Do I need to write separate 10 separate queries to get data? or have any other possible way to do it. I don't have an idea to how to get second, third, fourth... values from the records. please provide me a sample query to do this. thanks in advance

You can use Skip method to get specific record like this
private Location GetRecord(int skip)
{
return clientContext.Lobbies.Where(location => location.FkBranchId == locationRecord.FkBranchId && !location.FkAppointmentId.HasValue && location.Status == 1 && location.IsActive)
.OrderBy(location => location.AddedTime)
.Skip(skip)
.FirstOrDefault();
}
and use
var data = GetRecord(0);//First Record
var data = GetRecord(1);//Second record
var data = GetRecord(9);// 10th record

Do I need to write 10 separate queries to get data?
No, you can use Skip(n) to skip first n records and then get First record by FirstOrDefault()
Like,
private Location GetLocation(int skipIndex)
{
return clientContext.Lobbies
.Where(location => location.FkBranchId == locationRecord.FkBranchId
&& !location.FkAppointmentId.HasValue
&& location.Status == 1 && location.IsActive) //Filter using where clause
.OrderBy(location => location.AddedTime) //Order by AddedTime
.Skip(skipIndex) //Skip first n records
.FirstOrDefault(); //Take the record at given position.
}
You need to pass skipIndex = 2 as a parameter to get third Location.
var secondLocation = GetLocation(1);
var thirdLocation = GetLocation(2);
...

Related

how to to SUM specific column including the current data using LINQ

I have a query it should first add up the amount in the database starting from 3 months ago until the current date,and if its more than a specific amount which i put in the condition,it should return false.
public Task<bool> SecurityCheck(CustomerData cust)
{
var checkRsult = (from x in dbContext.CustomerModel
where x.CustomerReference == cust.CustomerReference
&& x.Created >= DateTime.Today.AddMonths(-3)
select new
{
AccomulateAmount = x.AmountToTransfer
}).Sum(x => x.AccomulateAmount);
}
var finalResult=checkRsult+cust.Amount;
if(finalResult>250000){
//return false
}
else{
//store th model in the db
}
first of all im not sure if the way i query is right or not(the LINQ part),my second question is ,is there any way to sum all including the current incoming one(cust.amount)inside a single query? Rather than get the database sum first and then add the current one to it?
It's slightly long winded, you could make it
dbContext.CustomerModel
.Where(cm => cm.CustomerReference == cust.CustomerReference && cm.Created >= DateTime.Today.AddMonths(-3))
.Sum(cm => cm.AmountToTransfer)

Retrieving data from sql to datagridview using LinqToSql

I have a datatable in sql and a datagridview in winform. datatable holds measurement results from a mould with a MouldID. For every measurement 50 lines of results are logged to table. To track measurement count for same mould, i also have MeasId column which incremented by 1 for every measurement input. Please see picture for table view.
What i need to do, retrieve only the rows with choosen MouldID (from a combobox) with last MeasID.
I tried following codes but i couldn't figure out how to group this rows with MeasId.
using (LinqDataClassesDataContext dataContext = new
LinqDataClassesDataContext())
{
// attemp 1
var query=dataContext.SupplierVals
.Where(m=>m.MouldID==comboBMouldID.SelectedValue.ToString())
.OrderByDescending(m => m.MeasId).FirstOrDefault();
// attemp 2
var query=dataContext.SupplierVals
.Where(mr=>mr.MouldID==comboBMouldID.SelectedValue.ToString())
.OrderByDescending(mr => mr.MeasId).Select();
// attemp 3
var query = (from x in dataContext.SupplierVals
where x.MouldID == comboBMouldID.SelectedValue.ToString()
select x).First();
// attemp 4
var query = from x in dataContext.SupplierVals
where x.MouldID == comboBMouldID.SelectedValue.ToString()
group x by x.MeasId into grp
select grp.OrderByDescending(x => x.MeasId).First();
daGridUnused.AutoGenerateColumns = false;
daGridUnused.Columns["unusedShowDist"].DataPropertyName = "Distnc";
daGridUnused.Columns["unusedShowAper"].DataPropertyName = "Apert";
daGridUnused.Columns["unusedShowTap"].DataPropertyName = "Taper";
daGridUnused.DataSource = query;
}
None of these queries return what i need from datatable.
What am i doing wrong?
It seems that you were almost there. You simply need to filter also by the Max value and order by the ValueId:
string mouldId = comboBMouldID.SelectedValue.ToString();
int max = dataContext.SupplierVals
.Where(m=>m.MouldID == mouldId)
.Max(m => m.MeasId);
var query=dataContext.SupplierVals
.Where(m=>m.MouldID == mouldId && m.MeasId == max).ToList();
disclaimer: this query can surely be optimized, I am working on a better solution

Filter entity using a string array is not working

I've researched and found that I use .Contains on the array to filter an entity, but my resulting list is empty what is wrong?
public List<Order> GetOrderstoShip()
{
var shipvia = new string[] { "UPS", "FED", "EX", "USP" };
var orders = db.Orders.Where(
x => x.VOID != "Y" && x.GONEDATE == "")
.ToList();
var exporders = orders.Where(
x => shipvia.Contains(x.SHIPVIA.ToUpper())
).ToList();
// Problem: exporders contains 0 items
// My database field contains the following:
// FEDEX, UPS, USPS, FEDEX GND, FEDEXGND
// And, I made sure orders has a list of 900+ items
return exporders;
}
New Development: I went into my DB and edited one record. I set the ShipVia field exaclty to UPS (previously it was UPS GND) and I got one item back in exporder.
That means the .Contains is exact match. So how do I get it to do something similar to the SQL Like?
I thought the whole point of using contains was that is does partial match.
Just a take a stab. You might have white space in your database table. You can try to trim the results first.
shipvia.Contains(x.SHIPVIA.Trim().ToUpper())
I would suggest doing this filter before the results are returned. This will speed up the database query time.
I had to use a work-around since I only had three strings to check for, I expanded my filter by using or... not the most elegant but it lets me continue with my project!
If anyone figures out why the .Contains is not working, please let me know...
public List<Order> GetOrderstoShip()
{
var shipvia = new string[] { "UPS", "FED", "EX", "USP" };
var orders = db.Orders.Where(
x => x.VOID != "Y" && x.GONEDATE == "" && (
x.SHIPVIA.Contains("UPS") ||
x.SHIPVIA.Contains("FED") ||
x.SHIPVIA.Contains("USP"))
).ToList();
var exporders = orders.Where(
x => shipvia.Contains(x.SHIPVIA.Trim().ToUpper())
).ToList();
// Problem: exporders contains 0 items
// My database field contains the following:
// FEDEX, UPS, USPS, FEDEX GND, FEDEXGND
// And, I made sure orders has a list of 900+ items
return orders;
}

The method ‘Skip’ is only supported for sorted input in LINQ to Entities. The method ‘OrderBy’ must be called before the method ‘Skip’

Using Entity Framework 6.0.2 and .NET 4.5.1 in Visual Studio 2013 Update 1 with a DbContext connected to SQL Server:
I have a long chain of filters I am applying to a query based on the caller's desired results. Everything was fine until I needed to add paging. Here's a glimpse:
IQueryable<ProviderWithDistance> results = (from pl in db.ProviderLocations
let distance = pl.Location.Geocode.Distance(_geo)
where pl.Location.Geocode.IsEmpty == false
where distance <= radius * 1609.344
orderby distance
select new ProviderWithDistance() { Provider = pl.Provider, Distance = Math.Round((double)(distance / 1609.344), 1) }).Distinct();
if (gender != null)
{
results = results.Where(p => p.Provider.Gender == (gender.ToUpper() == "M" ? Gender.Male : Gender.Female));
}
if (type != null)
{
int providerType;
if (int.TryParse(type, out providerType))
results = results.Where(p => p.Provider.ProviderType.Id == providerType);
}
if (newpatients != null && newpatients == true)
{
results = results.Where(p => p.Provider.ProviderLocations.Any(pl => pl.AcceptingNewPatients == null || pl.AcceptingNewPatients == AcceptingNewPatients.Yes));
}
if (string.IsNullOrEmpty(specialties) == false)
{
List<int> _ids = specialties.Split(',').Select(int.Parse).ToList();
results = results.Where(p => p.Provider.Specialties.Any(x => _ids.Contains(x.Id)));
}
if (string.IsNullOrEmpty(degrees) == false)
{
List<int> _ids = specialties.Split(',').Select(int.Parse).ToList();
results = results.Where(p => p.Provider.Degrees.Any(x => _ids.Contains(x.Id)));
}
if (string.IsNullOrEmpty(languages) == false)
{
List<int> _ids = specialties.Split(',').Select(int.Parse).ToList();
results = results.Where(p => p.Provider.Languages.Any(x => _ids.Contains(x.Id)));
}
if (string.IsNullOrEmpty(keyword) == false)
{
results = results.Where(p =>
(p.Provider.FirstName + " " + p.Provider.LastName).Contains(keyword));
}
Here's the paging I added to the bottom (skip and max are just int parameters):
if (skip > 0)
results = results.Skip(skip);
results = results.Take(max);
return new ProviderWithDistanceDto { Locations = results.AsEnumerable() };
Now for my question(s):
As you can see, I am doing an orderby in the initial LINQ query, so why is it complaining that I need to do an OrderBy before doing a Skip (I thought I was?)...
I was under the assumption that it won't be turned into a SQL query and executed until I enumerate the results, which is why I wait until the last line to return the results AsEnumerable(). Is that the correct approach?
If I have to enumerate the results before doing Skip and Take how will that affect performance? Obviously I'd like to have SQL Server do the heavy lifting and return only the requested results. Or does it not matter (or have I got it wrong)?
I am doing an orderby in the initial LINQ query, so why is it complaining that I need to do an OrderBy before doing a Skip (I thought I was?)
Your result starts off correctly as an ordered queryable: the type returned from the query on the first line is IOrderedQueryable<ProviderWithDistance>, because you have an order by clause. However, adding a Where on top of it makes your query an ordinary IQueryable<ProviderWithDistance> again, causing the problem that you see down the road. Logically, that's the same thing, but the structure of the query definition in memory implies otherwise.
To fix this, remove the order by in the original query, and add it right before you are ready for the paging, like this:
...
if (string.IsNullOrEmpty(languages) == false)
...
if (string.IsNullOrEmpty(keyword) == false)
...
result = result.OrderBy(r => r.distance);
As long as ordering is the last operation, this should fix the runtime problem.
I was under the assumption that it won't be turned into a SQL query and executed until I enumerate the results, which is why I wait until the last line to return the results AsEnumerable(). Is that the correct approach?
Yes, that is the correct approach. You want your RDBMS to do as much work as possible, because doing paging in memory defeats the purpose of paging in the first place.
If I have to enumerate the results before doing Skip and Take how will that affect performance?
It would kill the performance, because your system would need to move around a lot more data than it did before you added paging.

add item count to LINQ select

I have a problem I cant wrap my head around.
I have a Sharepoint List of Items, which have Categories. I want to read all Categories and count how often, they occur.
In another method, I want to take the categoryCount, divide it by the total number of tickets and multiply by 100 to get a percentage.
The problem is the Count.
This is my query so far:
public IEnumerable<KategorieVM> GetAllCategories()
{
int counter = 0;
var result = (from t in Tickets
where t.Kategorie != Kategorie.Invalid && t.Kategorie != Kategorie.None && t.Kategorie != null
select new KategorieVM() { _name = t.Kategorie.ToString(), _val = counter++ });
return result;
}
the problem is, I can't use counter++. Is there a clean workaround? The option to build a query for the purpose of counting each category is not a valid option. The list has 15000 Listitems and growing. In the end I need to iterate through every category and call the query to count the tickets which just takes about 3 minutes.
So counting the cateogry in one query is mandatory.
Any help is highly appreciated.
/edit: for the sake of clearity:
the counter++ as count was just a brainfart - I dont know why I tried it; this would have resulted in an index. I needed a way to count how often the 'category' occured in those 15k entries.
You can use GroupBy to perform the Count within the query itself:
return Tickets
.Where(t => t.Kategorie != Kategorie.Invalid && t.Kategorie != Kategorie.None && t.Kategorie != null)
.GroupBy(t => t.Kategorie.ToString())
.Select(g => new KategorieVM() { _name = g.Key, _val = g.Count() });

Categories