Improve performance in linq query - vb.net

We have a linq query as shown below to display items first it should display records matching with the text and next with if the text contains in the string.But it is causing lot of performance issue. Could any one pls help how to improve it.
Dim result1 = From entry As IAutoCompleteEntry In oldList
Where entry.ToString.ToUpper.Contains(Me.Text.ToUpper())
Order By entry.ToString.IndexOf(Me.Text.ToUpper()), entry.ToString.ToUpper.StartsWith(Me.Text.ToUpper())
Descending
Select entry

You are calling ToUpper() at several places. Is it possible to get your list/array to have a ToUpper() before you get into this linq query?
I think you can also have another column for entry.ToString.IndexOf(Me.Text.ToUpper()), entry.ToString.ToUpper.StartsWith(Me.Text.ToUpper()) before getting to this linq query.
It might improve on performance....

First, I'm not sure what the significance of the .StartWith has. Since you are already getting the IndexOf, you would already know the answer of StartsWith (it should be 0).
Next, you really shouldn't be using ToUpper (as #RobertMcKee mentioned), instead you should be using case insensitive comparisons. In that case, you shouldn't need the .ToUpper's anymore either...
Finally, I was actually going to say use contains for your second statement, but you probably don't even need it. You could just sort descending based on your entry variable. Here is an updated query I wrote up:
dim result1 = From entry As IAutoCompleteEntry In oldList
Where (entry.IndexOf(Me.Text, StringComparison.OrdinalIgnoreCase) <> -1)
Order By entry Descending
Select entry

Related

SQL - After group by filtering down to rows where column value = certain string

Not sure why this isn't working.
When I run the query without HAVING segment ilike 'Enterprise' I get results (see screenshot) but when I add it back in the query returns nothing despite clearly containing instances where segment = 'Enterprise'. I can't find any instances online where having is used to filter for strings so I'm thinking this just isn't possible. Could someone confirm if this is the case and if there is an alternative method if so? Thanks.
You can't use HAVING to filter for strings, you can only use it to filter for numeric values. To filter for strings, you'll need to use the WHERE clause.

Retrieve more than 255 characters from a query field

I have a query that displays more than 255 characters in a field, and I want to put that data into a variable that I can process. Unfortunately, MS Access truncates the field value return to 255 characters.
(At least when using this method:)
MyVar = Nz(rst.Fields("myfield").Value)
Most of the workarounds I've found online suggest to create a table, modify the desired field setting to Long Text, and then migrate the data from the query to the table, but I'm getting the same results. The Long Text field is still truncated during the DoCmd execution.
(At least when I do it this way:)
CurrentDB.Execute "Insert Into target_table Select myquery.* From myquery"
Other suggestions mention to change the field to group by "First", but the field reverts to "Expression" when run because the field definition includes a function that runs during the query to manipulate the results.
The query also isn't mine and is rather complicated, using other field expressions that call other functions across tables. I would like to avoid reverse engineering the entire thing just to update a table if at all possible. The data is already on my screen, looking at me - I just want to be able to use it.
It's a very Microsoft-ish solution for an MS product to display some data and then tell you it can't find the stuff it just gave you (I'm looking at you, file explorer), but I'm hoping someone here might have a viable suggestion. Perhaps some other query-to-table methods that don't truncate? Some other query setting, or field retrieval method?
Try this:
Dim MyVar As String
Dim Value As Variant
Value = rst.Fields("myfield").Value
MyVar = Nz(Value)
In any case, this works:
MyVar = Nz(DLookup("myfield", "myquery", "Id = " & someId & ""))
However, most likely your myquery is the limiting factor. It must be a straight select query to not truncate memo-fields.

LINQ result on datatable without for loop

I am sure this is easy (or that I am completely wrong), but all I want to do is get the single values against a LINQ query on a datatable and not use a for.. each loop to access them.
Scenario..
I have a datatable containing a number of rows. I run my query looking for a particular match on "EP" like such..
Dim qryB = From rw In oDT_Cables
Where rw("EP").Equals(br.Position)
Select ld = rw("LOAD"), tl = rw("TOT-LEN")
Now..
I know that I have only one result (due to checking upon insertion), so how do I simply access the items ld and tl without a for each loop??
I have tried:
qryb.elementat(1) error
qryb.elementat(ld) Not possible
qryb.tl not possible
Does anyone know how I can access tl and ld from the query please? It is much appreciated.
Brett
If you know for a fact that a LINQ query produces a single result then you call Single.
Dim result = qryB.Single()
If there may be no result but will never be more than one then you call SingleOrDefault and the result may be Nothing. If there will be at least one result but may be more and you want just the first, you call First. If there may be zero, one or more and you want the first if there is one then you call FirstOrDefault and the result may be Nothing.
Note that some LINQ providers don't support both options, e.g. LINQ to Entities (the LINQ provider for Entity Framework) supports First and FirstOrDefault but not Single or SingleOrDefault (unless it's changed recently) while, if I'm not mistaken, LINQ to SQL supports Single and SingleOrDefault but not First or FirstOrDefault.
Note that, if you were going to use ElementAt, you would have to specify 0 as the index. ElementAt works pretty much like indexing a array or other IList, so the first item is at index 0. You'd only use ElementAt for something in the middle of a query result though, given that you have Single, First and Last methods and their nullable equivalents.

MS Access Having Clause

Alright so I understand the point of the HAVING clause. I am having an issue and I am wondering if I can solve this the way I want to.
I want to execute one query using ADODB.Recordset and then use the Filter function to sift through the data set.
The problem is the query at the moment which looks like this:
SELECT tblMT.Folder, tblMT.MTDATE, tblMT.Cust, Sum(tblMT.Hours)
FROM tblMT
GROUP BY tblMT.Folder, tblMT.MTDATE, tblMT.Cust
HAVING tblMT.Cust LIKE "TEST*" AND Min(tblMT.MTDATE)>=Date()-30 AND MAX(tblMT.MTDATE)<=Date()
ORDER BY tblMT.TheDATE DESC;
So the above works as expected.... however I want to be able to use the tblMT.Cust as the filter without having to keep re querying the database. If I remove it I get a:
Data type mismatch in criteria expression.
Is what I am trying to do possible? If someone can point me in the right direction here would be great.
Ok... the type mismatch is caused because either tblmt.mtdate isn't a date field or tblmt.hours isn't a number field AND you have data that either isn't a date or isn't a number when the customer isn't like 'TEST*'. Or, for some customers, you have a NULL in mt.date and null can't be compared with >=. you'd still get the error if you said where tblMt.cust not like "TEST*" too.
Problem is likely with the data or your expectation and you need to handle it.
What data types are tblMT.hours and tblMt.MtDate?

Sorting results when autocomplete matches multiple columns in SQL

I've run into an issue with an autocomplete field I'm working on. The field I'm working with is composed of the form "<NAME> (<CODE>)". When a user starts typing in text, I want to display any results that match either NAME or CODE.
For example, if this list contains items and their codes, like "Personal Computer (PC)", then I'd want the list to pop up that row if the user types "P", "PC", "Per", etc.
I've gotten this to work fine in SQLite with a query like this:
SELECT *
FROM table
WHERE name LIKE "?%" or code LIKE "?%"
However, the problem I'm running into now is how to best sort the results that come back from this. For example, If someone enters "PC", I want "Personal Computer (PC)" to be the first result. However, if there's another row (you'll have to bear with me as this is contrived) "PC Case (301)", then there's no simple ordering I can do on the results to ensure that the best match appears first. Ordering by name and code both returns PC Case first.
I want a query where it returns the best match first, rather than items in alphabetical order. Is there such a function I can use in SQLite to get this, or should I return the results and then mess with the order in the code?
If it helps any, I'm using this for FilterQueryProviders on Android.
Yes, you should implement FullTextSearch and the use MATCH in your queries.
Ref: http://dotnetperls.com/sqlite-fts3
This is a long time after the fact, but I've solved my dilemma without having to resort to crazy sorting tactics.
Basically, once an autocomplete gets complex enough, you need to implement your own CursorAdapter (implementing FilterQueryProvider) then override convertToString(). That way, you end up being able to do complex queries via runQuery(), but can then convert it to readable form in convertToString().