LINQ Returning string array from DB.ExecuteQuery - vb.net

I am simply trying to return a list of strings (just one field in a table) using the LINQ function Db.Executequery, but the following does not compile
Dim names = datacontext1.ExecuteQuery(of String()) _
("Select customerName from customers",nothing)
It looks like I cannot simply return a list of strings, it has to be a user defined class. (I tried just String, List(of String),etc but no luck.) This is kind of cumbersome, because I cannot be declaring a class for each and every string field. (BTW, this will be a dynamic query, that is why I am not using the ORM mapping features)
The following does compile:
dim customerList = datacontext1.ExecuteQuery(of Customer) _
("Select * from customers",nothing)

The following should run just fine (assuming northwind database):
Dim names = datacontext1.ExecuteQuery(of String()) _
("SELECT contactname FROM customers")

Related

Convert an unknown structure to an untyped Object in VB.NET

I'd like to convert an unknown basic structure to an Object (no type here).
I'm building a library that will be used by many users to extract data from my system but don't want to do a new function for everyone of them. They have to know what will be the result.
In vb, it is possible to create an Object with some properties and use it as it is a regular Class like so:
Dim myObj as New With { .name = "Matt", .age = "28" }
MsgBox( myObj.name & " is now " & myObj.age & " years old.")
So far, so good.
Next step : my user will give me some instructions that I need to extract data from various DBs, and I've no idea of what the result will be.
What I know after the execution is a list of String containing the columns of the result set and, of course a (set of) rows.
And here is the problem of course
My function (for a single row) so far:
Public Function GetData(ByVal instructions as String) as Object ' User is supposed to know what will be inside, instructions is as XML describing DB, table, query, ...
' Do what is needed to retrieve data
' Here I have a variable cols As List(Of String) ' e.g. ("BP", "NAME", "VAT")
Dim o As New With ???
Return o
End Function
What I've tried: build a fake JSon on the fly, and try to Deserialize to Object.
But even if it seems to work, I (and the user) can't access the property as in my top piece of code like:
MsgBox(o.BP)
I know that I could do
Public Function GetData(Of T As {New})(ByVal instructions as String) As T
Dim o As T
' Use some Reflexion to TryInvokeMember of T
Return o
End Function
But I wanted to remove the hassle to create a class to use my code.
Plus, My librairy will be use in a webservice and the class of the user is then unknown.
One approach could be - to use Dictionary(Of String, Object)
Public Function GetData(instructions as String) As Dictionary(Of String, Object)
Dim data = ' Load data
Dim columns As String() = { "BP", "NAME", "VAT" }
Return columns.ToDictionary(
Function(column) column,
Function(column) data.GetByColumnName(column)
)
End Function
` Usage
Dim result = GetDate("instructions: ['BP', 'NAME']")
' Because user knows it is Integer
Dim bpValue = DirectCast(result.Item("BP"), Integer)
Thanks to #GSerg, #Fabio and a few other searches about ExpandoObject, I did it !
Imports System.Dynamic
Dim o As Object = New ExpandoObject()
For Each col In cols
DirectCast(o, IDictionary(Of String, Object)).Add(col, row.GetString(col))
Next

extract list of string from list of custom class

i have a list(of custom class)
and i want to extract a list of all 'name' String, from it, through linq
I know how to do with a loop, but i need to get it with a linear, brief linq instruction.
i've checked this help
C# Extract list of fields from list of class
but i have problem in linq correct syntax
in particular because i would like to extract a New List(Of String)
Class Student
Sub New(ByVal NewName As String, ByVal NewAge As Integer)
Name = NewName
Age = NewAge
End Sub
Public Name As String
Public Age As Integer
End Class
Public Sub Main
Dim ClassRoom as New List(Of Student) From {New Student("Foo",33), New Student("Foo2",33), New Student("Foo3",22)}
Dim OneStudent as Student = ClassRoom(0)
Dim AllStudentsNames As New List(Of String) From {ClassRoom.Select(Function(x) x.Name <> OneStudent.Name).ToList}
End Sub
But something wrong...
Any help?
P.S. Since c# it's close to vb.Net, also c# helps are well welcome.
First, you don't need to create a new list From the one returned by the LINQ method. It's already in a new list at that point, so you can just set AllStudentsNames equal directly to what the ToList method returns.
Second, you are not selecting the name. You are selecting the result of the equality test to see if the names are different. In other words, when you say Select(Function(x) x.Name <> OneStudent.Name), that returns a list of booleans, where they true if the names are different and false if the names are the same. That's not what you want. You want the list of names, so you need to select the name.
Third, if you need to filter the list so that it only returns ones where the name is different, then you need to add a call to the Where method.
Dim AllStudentsNames As List(Of String) = ClassRoom.
Where(Function(x) x.Name <> OneStudent.Name).
Select(Function(x) x.Name).
ToList()

Get SQL single value from query as String

I have the following code in my code behind:
Dim name As String
name.text= Staff.LoadName(StaffID)
The following query in my Class:
Public Function LoadName(ByVal ID As String)
Dim ds As New DataSet
Dim SQL As String = ""
SQL="select name from Staff where StaffID='" & ID & "' "
ds = Common.QueryDataByDataset(SQL)
ds.Tostring()
Return ds
End Function
But the name.Text doesn't show the value. How to I get the single value and convert it to string to display? Thanks
I am guessing the Common.QueryDataByDataset is from your library or some third party. Assuming it is executing the query and populating the dataset, you should be able to change the last two lines of the LoadName function to this:
String name = ds.Tables.Item("Staff").Rows(0)("name").ToString()
return name
You should add error handling in this method. For example, check to make sure the query returns exactly one result. Also, this method appears to be susceptible to SQL injection: http://en.wikipedia.org/wiki/SQL_injection

How to return an EntityBase2 from a string?

I have a ListBox that is populated with my entity names, i.e. A1AllocationHelp1Entity
On select I need to pass that string name to get an EntityBase2 type.
I can get it using reflection:
Public Function CreateEntity(ByVal entityName As String) As EntityBase2
Dim myAssembly = Assembly.LoadFrom(DALFileName)
Dim assemblyName = Split(dynamicAssembly.FullName, ",")(0)
Dim myEntityName = assemblyName & ".EntityClasses." & entityName
Dim handle = Activator.CreateInstance(assemblyName, myEntityName)
Dim entity = CType(handle.Unwrap(), EntityBase2)
Return entity
End Function
but if I have the types there that llblgen generates, I would like to be able to instantiate it somehow without resorting to reflection.
Is there any way I can do that?
All that refection code can be replaced with a single line
Return GeneralEntityFactory.Create( _
CType(System.Enum.Parse(GetType(EntityType), entityName), EntityType))
This returns the same type and is the answer I was looking for.

LLBLGen Pro: How to evaluate an EntityField for a given String

I have an LLBLGen Pro project which has generated VB.Net 2.0 Self Servicing code.
I have a function to return a list of custom structures based on a search using the generated code.
I would like to supply a Dictionary of FieldNames and Values to this function and for each one add a new Predicate Expression to the search.
How can I check the String within the dictionary that represents the Field name and work out which EntityField to add the Predciate Expression for?
Code Sample
Dim dbFiles As New AllFilesCollection
Dim dbFilter As New PredicateExpression
If Not String.IsNullOrEmpty(ClientName) Then
dbFilter.Add(New PredicateExpression(AllFilesFields.ClientMenuName = ClientName))
End If
If Not String.IsNullOrEmpty(SearchText) Then
dbFilter.Add(New FieldLikePredicate(AllFilesFields.ClientReference, "%" & SearchText & "%"))
dbFilter.AddWithOr(New FieldLikePredicate(AllFilesFields.Cmsnumber, "%" & SearchText & "%"))
End If
For Each Filter As KeyValuePair(Of String, String) In Filters
'Custom code here to determine the field to add a filter for.
Next
dbFiles.GetMulti(dbFilter)
I think that this question has been ignored because it looks like an LLBLGEN question, but it probably isn't.
If you know all of your Columns:
City
State
Zip
Then you just need to convert your string to those values like this...
For Each Filter As KeyValuePair(Of String, String) In Filters
Select Case filter.Key
Case "City"
dbFilter.Add(New PredicateExpression(AllFilesFields.City = filter.Value))
Case "State"
dbFilter.Add(New PredicateExpression(AllFilesFields.State = filter.Value))
Case "Zip"
dbFilter.Add(New PredicateExpression(AllFilesFields.Zip = filter.Value))
End Select
Next
You also could do something like this:
Dim fields As IEntityFields = new AllFieldsEntityFactory().CreateFields();
For Each Filter As KeyValuePair(Of String, String) In Filters
dbFilter.Add((EntityField) fields[Filter.Key] == Filter.Value);
Next