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.
Related
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
I'm building an interface on Flask using SQLAlchemy and part of it is a search API. Essentially a type-ahead input is calling the server with its value (for example an email) and then the server is performing a SQLalchemy query using .like in a filter like below
q = session.query(User).filter(User.email.like('%'+term+'%')).all()
This query isn't really returning anything useful and after the first few characters, nothing at all. But if I perform the same query with the term hardcoded, like so:
q = session.query(User).filter(User.email.like('%mysearchterm%')).all()
It will return results perfectly fine, so there's something with how I'm putting the term into the like() method but I really can't figure out what the issue is. The term is coming in from an ajax POST and the value is there on the server-side, just .like() isn't using it correctly.
By "nothing useful" I mean that the first sets of results coming back have nothing to do with the actual term being inputted, after a term of length higher than 3-4 no results are returned back despite matching items existing in the DB.
Any help greatly appreciated.
Issues been resolved. This query sat inside of a larger query builder function which applied limit and offset to the query later in the function, because the limit and offset were higher than the amount of results back the returned result set was empty.
Can chock this one up to bad human error and lack of sleep.
Take for example: a Person that has a collection of Pets. I want to only list the Persons that have at least 5 pets.
I have tried:
var result = (from a in UnitOfWork.CurrentSession.QueryOver<Person>()
where a.Pets.Count >4
select a
).List()
But it says it does not recognize the property Count (which makes sense because it is not a DB field). I also tried Count() and it still doesn't work saying it doesn't understand that function (throws exception).
I've tried all kinds of subqueries and criteria methods but I don't know enough to put it all together. And I don't know whether I shold use LINQ or HQL or QueryOver or Criteria...It would be much much mch easier in SQL but I don't want to "cheat"
I have been searching google like crazy, and everything I found either does not compile or I get a runtime error
You are using QueryOver instead of LINQ (Query<T>() extension method)
I have a very simple question but cannot find a simple answer.
I have NHibernate executing a raw SQL query, which unfortunately is loaded from the DB (yes, we store SQL query in the DB, not the best design but bear with me). This means that basically I have no idea how many columns the query will return.
What I know is that if the query is a single column then it is what I need and if it is more than one column then I need the first one, easy enough.
In my code I have basically 3 options:
session.CreateSQLQuery(SQLString).List();
session.CreateSQLQuery(SQLString).List<object>();
session.CreateSQLQuery(SQLString).List<object[]>();
Problem is that the List() will return either a List<int> (or the appropriate type, but int should be in my case) if the query returns a single column, or a List<object[]>() if I have multiple columns. Same goes for List<object> except that it will not return a List<int> in this case.
Of course trying to always cast to object[] (3rd option) and get the first element does not work, since nHibernate returns an int and that cannot be cast to object[].
Is there a way to force nHibernate to always return an object[] even in the case of a single column? If not, is there an easy way to check the number of columns in the result and act accordingly?
Thanks!
You should take a look at the differant result transformers NHibernate provides out of the box (you can write your own as well of course).
What might fit in your case would be the NHibernate.Transform.ToListResultTransformer. AFAIK, it transforms your result to an IList, where each entry contains an IList again.
So:
IList items = session
.CreateSQLQuery(query)
.SetResultTransformer(new NHibernate.Transform.ToListResultTransformer())
.List()
if(((Ilist)items[0]).Count == 1)
// just one columns
else
// more columns or zero
My company has just started using LINQ and I still am having a little trouble with the abstractness (if thats a word) of the LINQ command and the SQL, my question is
Dim query = (From o In data.Addresses _
Select o.Name).Count
In the above in my mind, the SQL is returning all rows and the does a count on the number rows in the IQueryable result, so I would be better with
Dim lstring = Aggregate o In data.Addresses _
Into Count()
Or am I over thinking the way LINQ works ? Using VB Express at home so I can't see the actual SQL that is being sent to the database (I think) as I don't have access to the SQL profiler
As mentioned, these are functionally equivalent, one just uses query syntax.
As mentioned in my comment, if you evaluate the following as a VB Statement(s) in LINQPad:
Dim lstring = Aggregate o In Test _
Into Count()
You get this in the generated SQL output window:
SELECT COUNT(*) AS [value]
FROM [Test] AS [t0]
Which is the same as the following VB LINQ expression as evaluated:
(From o In Test_
Select o.Symbol).Count
You get the exact same result.
I'm not familiar with Visual Basic, but based on
http://msdn.microsoft.com/en-us/library/bb546138.aspx
Those two approaches are the same. One uses method syntax and the other uses query syntax.
You can find out for sure by using SQL Profiler as the queries run.
PS - The "point" of LINQ is you can easily do query operations without leaving code/VB-land.
An important thing here, is that the code you give will work with a wide variety of data sources. It will hopefully do so in a very efficient way, though that can't be fully guaranteed. It certainly will be done in an efficient way with a SQL source (being converted into a SELECT COUNT(*) SQL query. It will be done efficiently if the source was an in-memory collection (it gets converted to calling the Count property). It isn't done very efficiently if the source is an enumerable that is not a collection (in this case it does read everything and count as it goes), but in that case there really isn't a more efficient way of doing this.
In each case it has done the same conceptual operation, in the most efficient manner possible, without you having to worry about the details. No big deal with counting, but a bigger deal in more complex cases.
To a certain extent, you are right when you say "in my mind, the SQL is returning all rows and the does a count on the number rows". Conceptually that is what is happening in that query, but the implementation may differ. Compare with how the real query in SQL may not match the literal interpretation of the SQL command, to allow the most efficient approach to be picked.
I think you are missing the point as Linq with SQL has late binding the search is done when you need it so when you say I need the count number then a Query is created.
Before that Linq for SQL creates Expression trees that will be "translated" in to SQL when you need it....
http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx
http://msdn.microsoft.com/en-us/netframework/aa904594.aspx
How to debug see Scott
http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx
(source: scottgu.com)