Linq union for extra row not from table - sql

VB examples please
I need to return the same results from linq as I get using SQL
SELECT DISTINCT Area, Region
FROM dbo.Regions
Union
SELECT null,'All'
Order by 1,2
I use this for showing an "All" selecting in a combo box
My current linq points to a view that does the union for me but I want to know how to do it right in linq. I can't figure out how to union a row for the null,'All' values.
Public Shared Function GetRegions(ByVal Area As String) As IEnumerable
Dim DB As New SiteDBDataContext
Return From values In DB.uv_Areas _
Where values.Area = Area Or Area = "" Or values.Area Is Nothing _
Order By values.Region _
Select values.Area, values,Region
End Function
Thanks

You can't do it in the DB with Linq to SQL or Entity Framework, but you can do it in memory with Linq to Objects:
Public Shared Function GetRegions(ByVal Area As String) As IEnumerable
Dim DB As New SiteDBDataContext
Dim query = _
From values In DB.uv_Areas _
Where values.Area = Area Or Area = "" Or values.Area Is Nothing _
Order By values.Region _
Select New With { values.Area, values.Region }
Dim all = { New With { .Area = DirectCast(Nothing, String), .Region = "All } }
Return all.Concat(query)
End Function

Related

Inner Join in Entity Framework - how?

I am new to Entity Framework and I have this SQL query:
SELECT
WarningTypes.WarningTypeID, WarningTypes.WarningDescription,
WarningTypes.WarningArDescription, WarningReasons.ReasonName
FROM
WarningTypes
INNER JOIN
WarningReasons ON WarningTypes.WarningReasonID = WarningReasons.ID
and I need to convert this to be entity frame work so I Wrote this vb.net code:
Public Function selectAllWarningTypes() As System.Linq.IQueryable
'Dim dt As New DataTable
'wt.selectAllWarningTypes(dt)
Dim query = _
From warningTypes In objSRSEntities.WarningTypes _
From warningReasons In objSRSEntities.WarningReasons _
.Where(Function(wr) wr.ID = warningTypes.WarningReasonID) _
Select warningTypes = warningTypes, warningReasons = warningReasons
Return query
End Function
The problem is: this run time error returned when I set result in gridview:
Data binding directly to a store query (DbSet, DbQuery, DbSqlQuery, DbRawSqlQuery) is not supported
Thanks.

VB Running grouped LINQ into DataTable

I'm trying to run a LINQ to datatable, that normally works for me. This time I'm trying something new to me, Grouping and taking the first row from each group. questionGroups is of type IEnumerable(Of Object). When I open the query in the debugger I see a collection of DataRows, each with an ItemArray of the values I expect in the columns. How do I run this query to a DataTable, or select the two columns I want and run those into a Dictionary?
Public member 'ToTable' on type 'WhereSelectEnumerableIterator(Of
VB$AnonymousType_0(Of Object,IEnumerable(Of Object)),Object)' not
found.
Dim answerGroup As String = "QuestionSortKey"
Dim answerNo As String = "AnswerNo"
Dim surveyDefinitionNo As String = "Pk_SurveyDefinitionNo"
Dim query = _
From rows In surveyAnswerKeys.Rows _
Where rows(answerNo) IsNot Nothing _
Order By Guid.NewGuid() _
Group By questionSortKey = rows(answerGroup) _
Into questionGroups = Group _
Select questionGroups.First()
Dim randomAnswerNos As DataTable = query.ToTable
Edit: This question is an offshoot of this one: VB LINQ - Take one random row from each group

Converting LINQ Result to String VB.NET

I have a module that is correctly pulling a Linq query and writing it to a text file. I just need to know how to convert this to the actual string value. Thanks.
Imports System.IO
Module CheckExists
Public objStreamWriter As StreamWriter
Public Function SimpleQ4()
Dim dc As New DatabaseDataContext
Dim q = _
From a In dc.GetTable(Of tblDealer)() _
Where a.chvDealerName = "Something" _
Select a
Return q.ToString
objStreamWriter = New StreamWriter("path.txt")
objStreamWriter.WriteLine(q)
End Function
End Module
This is returning in myt text file
SELECT [t0].[iD], etc....
Public Function SimpleQ4()
Dim dc As New DatabaseDataContext
Dim q = _
From a In dc.GetTable(Of tblDealer)() _
Where a.chvDealerName = "Something" _
Select New With
{
myFirstColumn = a.columnName,
mySecondColumn = a.anotherColumnName,
...
}
objStreamWriter = New StreamWriter("path.txt")
objStreamWriter.WriteLine(q)
End Function
The LINQ query will not have data until the streamwriter actually starts writing data due to LINQs deferred execution.
Inside the curly braces you are creating an anonymous type. Every column you want a property for would be on the left side of the equal sign. If you don't want to create and map all of the columns use this instead:
From a In dc.GetTable(Of tblDealer)() _
Where a.chvDealerName = "Something" _
Select a
If you need to see the contents of the query, add q.ToList() on the line before creating the streamwriter.
The following code works
Public Sub textFile()
Dim ddc As New DatabaseDataContext
Dim q = _
(From a In ddc.GetTable(Of Table)() _
Where a.Name = "Something" _
Select a.Name).ToList
For Each item In q
objStreamWriter.WriteLine(item)
Next
End Sub

How can I use Linq to entities to group a collection without using anonymous types?

The documentation has an example about grouping on multiple properties:
Dim custRegionQuery = From cust In db.Customers _
Group cust.ContactName By Key = New With _
{cust.City, cust.Region} Into grouping = Group
For Each grp In custRegionQuery
Console.WriteLine(vbNewLine & "Location Key: {0}", grp.Key)
For Each listing In grp.grouping
Console.WriteLine(vbTab & "{0}", listing)
Next
Next
Suppose I have a real type (i.e. not anonymous) that has properties for each element of the key, as well as a property for the group, so something a little like:
Public Class CustomerRegionGroup
Public Sub New(city As String, region as String, customers As IEnumerable(Of Customer))
Me.City = city
Me.Region = region
Me.Customers = customers
End Sub
Public Property City As String
Public Property Region As String
Public Property Customers As IEnumerable(Of Customer)
End Class
Is it possible to rewrite the original query to just return IEnumerable(Of CustomerRegionGroup), or do I have to use the anonymous type, and run a second query on the result of the first?
Turns out it was a lot simpler than some of the things I'd tried, as I didn't appreciate that you could just do:
Dim custRegionQuery = From cust In db.Customers _
Group By cust.City, cust.Region _
Into Group _
Select New CustomerRegionGroup(City, Region, Group)

JQGrid on ASP.Net MVC with VB.Net

I am trying to make a JQGrid for a simple table.
After following through with a VB translated version from
http://haacked.com/archive/2009/04/14/using-jquery-grid-with-asp.net-mvc.aspx
from
http://www.qa.downappz.com/questions/jqgrid-sorting-in-vb-net-mvc-app.html
I modified it to my own database and came up with this function
Public Function SelectGridData(ByVal sidx As String, ByVal sord As String, ByVal page As Integer, ByVal rows As Integer) As ActionResult
Dim context As New IssueDBEntities
Dim pageIndex As Integer = Convert.ToInt32(page) - 1
Dim pageSize As Integer = rows
Dim totalRecords As Integer = context.Issues.Count()
Dim totalPages As Integer = CInt(Math.Ceiling(CSng(totalRecords) / CSng(pageSize)))
Dim jsonData = New With { _
.total = totalPages, _
.page = page, _
.records = totalRecords, _
.rows = (From p In context.Issues _
Order By (p.ID & " " & sord) _
Select New With {.id = p.ID, .cell = _
{p.ID, p.Image_Path, p.Magazine_Type,p.Magazine_Path}}).ToArray()}
Return Json(jsonData, JsonRequestBehavior.AllowGet)
End Function
The grid does show up without any data, and the system throws an error
The error description says
"Unable to cast the type 'System.Int32' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types."
Any help is appreciated, if this is due to some basic misunderstanding, please guide me, I am willing to do some hard work.
Thank you
Edit: The code that finally worked as per Oleg's Suggestion
Dim Simple_Object As IQueryable(Of Object)
Dim Second_Simple_Object As IQueryable(Of Object)
Dim My_Array As Array
Dim My_Second_Array As Array
Simple_Object = From p In Context.Issues _
Order By (p.ID & " " & sord) _
Select New With {p.ID, p.Image_Path, p.Magazine_Type, p.Magazine_Path}
My_Array = Simple_Object.ToArray()
Second_Simple_Object = From p In Context.Issues _
Order By (p.ID & " " & sord) _
Select New With {p.ID}
My_Second_Array = Second_Simple_Object.ToArray()
Dim My_Result(0) As My_Record_Type
For i = 0 To My_Array.GetLength(0) - 1
If i > 0 Then
ReDim Preserve My_Result(i)
End If
My_Result(i) = New My_Record_Type
My_Result(i).id = CInt(My_Second_Array(i).ID)
My_Result(i).Cell = {My_Array(i).ID.ToString, My_Array(i).Image_Path.ToString, _
My_Array(i).Magazine_Type.ToString, My_Array(i).Magazine_Path.ToString}
Next
Class My_Record_Type
Public id As Integer
Public Cell As String()
End Class
You try to fill rows property in one step. The problem is that you use Entity Framework which have some restrictions in the conversion of the data types. You can solve the problem if you first make query to get the items which you need without any data conversion and save intermediate results as List of items. After that you can make another LINQ Query where you include explicit conversion of p.ID to string. Moreover your current code don't use any paging of data. So the user will never seen more as the first page if you don't use loadonce: true.
It's difficult for me to write correct code in VB without debugging it. I use C# instead since last years. I recommend you to look at the answer for more information. It contains implementation of the server side filtering. If you don't need it and remove the corresponding code the rest code will be very short and I hope it will be easy to understand.
Here is complete sample of JQgrid with ASP.NET MVC 3 + C# (you can convert it to vb.net)
http://www.dotnetacademy.blogspot.in/2012/04/using-jqgrid-in-aspnet-mvc-3.html