"Runtime errors might occur when converting 'system.linq.IQueryable(of String)' to 'String' - vb.net

I am creating a feature where I allow a user to type in an email address and click "Search". This will search my database and return the email address, which I will then use in other methods to randomly generate passwords and email them. Language is ASP.VB and database is LINQ. I am getting an error to say "Runtime errors might occur when converting 'system.linq.IQueryable(of String)' to 'String' "
The code segment is:
Protected Sub btnSearchEmail_Click(sender As Object, e As System.EventArgs) Handles btnSearchEmail.Click
Dim db As New DatabaseDataClassesDataContext()
GlobalVariables.SearchUserEmail = txtSearchEmail.Text
GlobalVariables.CurrentEmailAddress = (From u In db.User_Signons
Where u.Email = SearchUserEmail
Select u).Distinct
End Sub
Any thoughts on how I can get around this. The global variables are both "As String" and the field in the DB is varchar. Thanks in advance

The Distinct call returns a sequence of strings, and the property you are assigning to is just one single string. Consider using First or FirstOrDefault instead of Distinct.

The problem is here:
GlobalVariables.CurrentEmailAddress = (From u In db.User_Signons
Where u.Email = SearchUserEmail
Select u).Distinct
Distinct returns a collection of distinct values. If you just want one value use
var user = (From u In db.User_Signons
Where u.Email = SearchUserEmail
Select u).First
GlobalVariables.CurrentEmailAddress = user.Email
' Do something with password
Note that :
This only gives you the first value (obviously)
It will throw an exception if there are NO results (use FirstOrDefault to return a default value (null for strings) if that is a legitimate possibility.

Related

Empty result on native SQL query on Hibernate

I am trying to develop a simple method to execute sql queries on my application so I can use native sql for certain things.
This is the method I have:
Session session = getReportCsvMgr().getHibernateSession();
session.beginTransaction();
String sql = String.format("select USER_ID from Users where accountid = 'testaaa'");
Object o = session.createSQLQuery(sql).list();
System.out.println(o.toString());
session.close();
I do not get any errors but somehow the object o is empty and the sysout just prints [].
I debugged and the session works. I tested changing the name of the table and indeed it said "table does not exist". I also tried with and update statement, no errors but it does nothing.
Can anybody tell me what I need to do?
Thanks!
Change the line
Object o = session.createSQLQuery(sql).list();
to:
List<Integer> o = session.createSQLQuery(sql).list();
it the USER_ID is integer or to:
List<String> o = session.createSQLQuery(sql).list();
if the USER_ID is string.
Moreover in a query you have not passed params so you can change:
String sql = String.format("select USER_ID from Users where accountid = 'testaaa'");
to simple:
String sql = "select USER_ID from Users where accountid = 'testaaa'";
Either use .uniqueResult() instead of .list() if it only returns one row or change the return type to List<Object[]>

Dealing with LINQ to Objects when object not found

I am using Linq statement as per below to find student name by its ID. It works fine. However there are cases where there is no student with given ID. In those cases an error is thrown "Object reference not set to an instance of an object."
How to efficiently deal with this problem?
Dim Name As String = Students.FirstOrDefault(Function(Student) Student.ID = "NO00007").Name
If you are satisfied with Name being null if there is no matching student, you can use the null conditional operator for member access:
Dim Name As String = Students.FirstOrDefault(Function(Student) Student.ID = "NO00007")?.Name
As usually answer is "it depend" - it depend on how you will use result you will get
If you want get some "default"/empty string instead of name when collection doesn't contain item
Dim result = Students.Where(Function(student) student.ID = "NO00007").
Select(Function(student) student.Name).
DefaultIfEmpty(String.Empty).
First()
Almost same approach if you want to get some "empty" object instead of null
Dim resultStudent = Students.Where(Function(student) student.ID = "NO00007").
DefaultIfEmpty(New Student With { .Name = "empty" }).
First()
From performance point of view approach above are same as FirstOrDefault - but provide little bid better readability(subjective of course)

conversion C# to vb.net issue

I am trying to convert C# to vb.net in WCF, the given below is the line of code
var user = from u in users
where u.Key == Id
select u.Value;
On using the conversion tool I get the following result
Dim user = _Where u.Key = Id
but simultaneously I get an error 'End of statement expected'
What am I doing wrong? Can anybody help me out on this?
It's about the same using query syntax really:
Dim users = From user In users
Where user.Key = Id
Select user
The Select is degenerate and if you would prefer, you could use method syntax instead:
users.Where(Function(user) user.Key = ID)
Try this:
Dim user = From u in users
Where u.Key = Id
Select u.Value
Dim user = From u in users Where u.Key = id
Select u.Value
You could also use a lambda.
Dim user = users.FirstOrDefault(Function(u)u.Key = id)
In the Lambda I used FirstOrDefault as you are using a key. This mean when the first record has been found, no extra time is wasted on searching the rest of the collection. it also means user will be null if nothing is found. If it was just a Where clause you would potentially end up with an empty collection.

LINQ to Entities .contains is ignoring results with NULL

I am new to the Entity Framework, and am struggling with what I hope is a basic problem. My code is here:
Dim accounts As List(Of STUDENT) =
(From a In SA.STUDENTs
Where (a.MATRIC_NO.Contains(matric) And a.FIRST_NAME.Contains(firstName) And a.MIDDLE_NAMES.Contains(middleName) And a.SURNAME.Contains(lastName) And a.PREFERRED_NAME.Contains(preferredName))
Select a).ToList
The query runs fine, until one of the search fields is NULL in the database. If, for instance, a matric number is entered in the seach interface but middle name is left blank, the query will not return any records if middle name is NULL in the database. If middle name is a blank space in the database then it will return the record.
Can anyone offer any pointers?
Many thanks!
You can add an extra check in your query. For example:
public function filterList(IEnumerable list, string name)
{
var filtered_list = list.Where(x=> x.Name.Contains(name) || string.IsNullorWhitespace(name)).ToList();
return filtered_list;
}
So you can see, if the name variable is empty, all elements will return true, so all elements will be return (no real filter applied).
So basically, you can change all filters from
something.Contains(anotherthing)
to
something.Contains(anotherthing) || string.IsnullOrWhitespace(anotherthing)
(From a In SA.STUDENTs
Where isnull(a.MATRIC_NO.Contains(matric) And a.FIRST_NAME.Contains(firstName) And a.MIDDLE_NAMES.Contains(middleName) And a.SURNAME.Contains(lastName) And a.PREFERRED_NAME.Contains(preferredName))
Select a).ToList
Like this `:select * from tbl where statusid = isnull(#statusid,statusid)
try like this ..
Dim get_rmf_2 = From rmf In t_rmf _
Where Not IsDBNull(rmf!NIVP) AndAlso rmf!NIVP = nivp_rap
this is in VB I think this is works fine
I managed to solve this using a different approach. If there was no value entered for a particular field, leave it out the query. I accomplished this using predicates, as below:
'create the base query
Dim accounts =
(From a In SA.STUDENTs
Select a)
'create predicates for each condition required in the query
If matric <> "" Then
accounts = accounts.Where(Function(m) m.MATRIC_NO.Contains(matric))
End If
If firstName <> "" Then
accounts = accounts.Where(Function(f) f.FIRST_NAME.Contains(firstName))
End If
If middleName <> "" Then
accounts = accounts.Where(Function(mn) mn.MIDDLE_NAMES.Contains(middleName))
End If
If lastName <> "" Then
accounts = accounts.Where(Function(l) l.SURNAME.Contains(lastName))
End If
If preferredName <> "" Then
accounts = accounts.Where(Function(p) p.PREFERRED_NAME.Contains(preferredName))
End If
'execute the query
Dim accountlist = accounts.ToList
'return the results
Return accountlist
If anyone can see anything wrong with this, or any gotchas that I'm unaware of, please let me know! I'm very new to LINQ to Entities, and LINQ in general!

Determine the type of Object to use to store a Linq Query

I am using VB .Net for this, so I don't have access to var or this would be a simple matter.
Right now my query is as follows
Dim errors As IOrderedQueryable(Of IGrouping(Of String, RSError)) = (From e In db.RSErrors
Where e.UserID = "msarchet"
Group e By e.Type Into t = Group).AsEnumerable
So I used this query in LinqPad to help me determine what the object would look like. I got back a IOrderQueryable(Of RSError) which then contained a IGrouping(Of String, RSError) for each grouped collection of objects returned by the query.
However I ended up with the current object type of errors as IOrderedQueryable(Of IGrouping(Of String, RSError)) because of the cast error I am getting in VS.
Unable to cast object of type 'System.Data.Linq.DataQuery1[VB$AnonymousType_12[System.String,System.Collections.Generic.IEnumerable1[RSSAdmin2.RSError]]]' to type 'System.Linq.IOrderedQueryable1[System.Linq.IGrouping2[System.String,RSSAdmin2.RSError]]'.
I'm not sure how to get rid of the VB$AnonymousType_1 Part of the returned object.
Am I even on the right track here or am I missing something completely?
Can you try the following
Dim errors = (From e In db.RSErrors
Where e.UserID = "msarchet"
Group e By e.Type Into t = Group).AsEnumerable
Doing it this way basically sets it to
Dim errors As Object [Whatever the expression returns]