Linq Query on int using string - linq

I'm trying to query the unique reference number of a table using Linq to Entities. The ID is provided via a textbox and hence a string in my code. Obviously in the database table the field is an integer so I have tried using .ToString first and then .Contains in the same way you would with a varchar(). This doesn't seem to work, with the error coming from the .ToString method.
How do you do this? I have tried converting the textboxes content to an integer but this then means the user would have to enter the exact int instead of a partial number.
Many Thanks

I'm not sure why toString do not work for you. I've tried this to methods. Both returned answers:
List<int> ids = new List<int>() { 111, 211, 311, 422, 522, 622, 733, 833, 933 };
string query = "11";
var result = ids.Where(id => id.ToString().Contains(query));
var result2 = ids.ConvertAll<string>(i => i.ToString()).Where(id => id.Contains(query));
// Both return the first three items

int value;
if(int.TryParse(someTextString,out value))
{
//do work here using integer comparision with 'value'
}
Whatever do you mean by "partial" value? Whatever you are "adding" to the user supplied string, you can still do before you parse the value. Your explanation is not very clear.
If you are indeed trying to make a wildcard search, this will fail using Linq-to-entities against a DB int value. I doubt lte will make much sense of sometable.intvalue.ToString().Contains(). In this case, you might need to do some client side maths to figure out what ranges need retrieving, or to write a stored procedure that does the search at the SQL end..

Related

Getting max value on server (Entity Framework)

I'm using EF Core but I'm not really an expert with it, especially when it comes to details like querying tables in a performant manner...
So what I try to do is simply get the max-value of one column from a table with filtered data.
What I have so far is this:
protected override void ReadExistingDBEntry()
{
using Model.ResultContext db = new();
// Filter Tabledata to the Rows relevant to us. the whole Table may contain 0 rows or millions of them
IQueryable<Measurement> dbMeasuringsExisting = db.Measurements
.Where(meas => meas.MeasuringInstanceGuid == Globals.MeasProgInstance.Guid
&& meas.MachineId == DBMatchingItem.Id);
if (dbMeasuringsExisting.Any())
{
// the max value we're interested in. Still dbMeasuringsExisting could contain millions of rows
iMaxMessID = dbMeasuringsExisting.Max(meas => meas.MessID);
}
}
The equivalent SQL to what I want would be something like this.
select max(MessID)
from Measurement
where MeasuringInstanceGuid = Globals.MeasProgInstance.Guid
and MachineId = DBMatchingItem.Id;
While the above code works (it returns the correct value), I think it has a performance issue when the database table is getting larger, because the max filtering is done at the client-side after all rows are transferred, or am I wrong here?
How to do it better? I want the database server to filter my data. Of course I don't want any SQL script ;-)
This can be addressed by typing the return as nullable so that you do not get a returned error and then applying a default value for the int. Alternatively, you can just assign it to a nullable int. Note, the assumption here of an integer return type of the ID. The same principal would apply to a Guid as well.
int MaxMessID = dbMeasuringsExisting.Max(p => (int?)p.MessID) ?? 0;
There is no need for the Any() statement as that causes an additional trip to the database which is not desirable in this case.

LINQ syntax - ordering of criteria

I'm trying to understand LINQ syntax and getting stuck. So I've got this line which gets all of the people with the postcode I'm searching for
IQueryable<int> PersonIDsWithThisPostcode = _context.Addresses
.Where(pst => pst.Postcode.Contains(p))
.Select(b => b.PersonID);
This line then only returns people in PersonIDsWithThisPostcode
persons = persons.Where(ps => PersonIDsWithThisPostcode.Contains(ps.PersonID));
I'd have expected it to be something along the lines of this, where you're looking at a container, then checking against a subset of values to see what you want.
persons = persons.Where(ps => ps.PersonID.Contains(PersonIDsWithThisPostcode));
So from a SQL point-of-view I'd think of it something like this
bucket = bucket.Where(bucket.Contains(listoffish));
but it seems to act like this
bucket = bucket.Where(listoffish.Contains(bucket));
I've read through lots of documentation but I can't get my head around this apparently simple notion. Any help to explain this way of thinking would be appreciated.
Thanks
If PersonID is an int you can't use ps.PersonID.Contains because an int is not a collection (or string which would search a substring).
The only correct way is to search your PersonId in a collection which is the PersonIDsWithThisPostcode-query that returns all matching PersonIds.
A single PersonID doesn't contain a collection but a collection of PersonIds contains a single PersonId.
So this is correct, it returns all persons which PersonId is in the other sequence:
persons = persons.Where(ps => PersonIDsWithThisPostcode.Contains(ps.PersonID));
and this not:
persons = persons.Where(ps => ps.PersonID.Contains(PersonIDsWithThisPostcode));
The syntax is reversed in comparison to SQL, which should come as no surprise, considering that C# and SQL are two different languages.
In SQL you place the list on the right, because IN operator reads "item in collection"
WHERE someId IN (100, 102, 113, 200, 219)
In C#, without regard to LINQ, you check if a collection contains an item using code that reads "collection contains item"
myList.Contains(someId);
When you use Contains in LINQ that gets translated to SQL, LINQ provider translates one syntax to the other syntax to shield C# programmers from thinking about the differences.

Dynamic Linq Select

I am having trouble wrapping my head around the Dynamic LinQ select. I have read Scott Gu's blog and each of the suggested posts but still cannot get my little brain to understand. I need to query an entity object passing in a variable for the column name. Assume an entity (table) containing 3 columns named: Mon, Tue & Wed. These contain data for each record. I do not know the column to hit at compile time so I need to pass a column name into the query. How can I accomplish this either using DLink or directly using Expression Trees?
Don't need Dynamic LINQ for that...
var columniwant="Mon"; // Or "Tue" or "Wed"
var query=db.stuff here;
IQueryable<string> result;
switch(columniwant)
{
case "Mon": result=query.Select(q=>q.Mon); break;
case "Tue": result=query.Select(q=>q.Tue); break;
case "Wed": result=query.Select(q=>q.Wed); break;
}
That said, I would think this would work:
var result=db.stuff here.Select(columniwant);

Filter records using Linq on an Enum type

I'm hoping this is a simple solution. I have a field (PressType) in a table (Stocks) that is seed populated by using an Enum. The table stores the data as an integer. However when I want to query some data via Linq it gives me issues. I can filter any other fields in the table using this format however on the Enum populated field it says
the "==" operator cannot be applied to operands of type "Models.PressType" and "string".
Any help you could give would be appreciated, thanks.
var test = db.Stocks.Where(x => x.PressType == myValue);
There is nothing wrong with your Linq. Your problem is that myValue is of type string. You need to convert your string to the enum first.
string myValue = SomeControl.Text;
Models.PressType myValueAsEnum = (Models.PressType)
Enum.Parse(typeof(Models.PressType), myValue);
IQueryable<Stock> test = db.Stocks.Where(x => x.PressType == myValueAsEnum);

LINQ to SQL simple query to get single int value

IQueryable<double?> query = (from t in ctx.MyList orderby t.MyNums select t.MyNums).Take(1);
IQueryable<double> q2 = query.Cast<double>();
IEnumerator<double> enumerator = q2.GetEnumerator();
while (enumerator.MoveNext())
{
double d = enumerator.Current;
return System.Convert.ToInt32(d);
}
The context for the above code is that I'm attempting to get the greatest integer value from a SharePoint list column. SharePoint seems to treat all list item values as "Number" so that's the reason that I initially had "double?" and not "int?". How could I write that query better? Also, at the moment, it doesn't work at all.. it says "Can only specify query options (orderby, where, take, skip) after last navigation." What does that mean? Thanks..
Additional Information e.g. "Why Max() doesn't work in SharePoint Web Services"
Go to the following link: http://msdn.microsoft.com/en-us/library/dd673933.aspx. The note contained there says the following:
The set of queries expressible in the LINQ syntax is broader than those enabled in the representational state transfer (REST)-based URI syntax that is used by data services. A NotSupportedException is raised when the query cannot be mapped to a URI in the target data service.
Did you try using Max instead?
double max = ctx.MyList.Max(t => t.MyNums);
return (int) max;
Don't forget to check for a null value in case all items in the list are null
return (int)(ctx.MyList.Max(x => x.MyNums) ?? 0);

Resources