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
Related
I have a collection in MongoDB and I'm using MongoDB Driver in VB net. I want to update several documents depending on a condition.
For this, I want to use LINQ, but the select causes an error and I don't know how to fix it.
Here's the code:
Dim update_for As UpdateBuilder
Dim query_for As IMongoQuery
Dim coll_for = db.GetCollection(Of MyClass)("collection_1")
Dim queryMun = (From a In coll_for _
Where (a.field_1 < 10000) _
Select a)
For Each emp In queryMun
query_for = Query.EQ("_id", emp.Id)
update_for = Update.Set("field_1", BsonValue.Create("0" + emp.field_1))
coll.Update(query_for, update_for, opts)
Next
When it executes de For Each sentence, it raises the exception: Unsupported where clause: (Boolean)Operators.CompareObjectLess(a.field_1, 10000, true).
What am I doing wrong?
Thank you very much for your help.
I think the error is clear:
You can't use a Less Than "<" operator in you WHERE clause because it's unsupported.
I have found a way to do this update based on the value of the attribute itself. What I want to do is add a "0" at the beginning of the attribute value, for example, if field_1=4567, after the update field_1='04567'.
Here's the code:
Dim update_for As UpdateBuilder
Dim query_for As IMongoQuery
Dim opts = New MongoUpdateOptions
opts.Flags = UpdateFlags.Multi
Dim coll_for = db.GetCollection(Of MyLINQClass)("collection_1")
Dim queryMun2 As New QueryDocument
Dim query_1 = Query.LT("field_1", MongoDB.Bson.BsonValue.Create(10000))
queryMun2.AddRange(query_1.ToBsonDocument)
Dim queryMun = coll_for.Find(queryMun2)
For Each emp In queryMun
query_for = Query.EQ("_id", emp.Id)
update_for = Update.Set("field_1", BsonValue.Create("0" + emp.FField_1.ToString))
coll.Update(query_for, update_for, opts)
Next
And here is the definition of MyLINQClass:
Public Class MyLINQClass
<BsonElementAttribute("_id")> _
Public Property Id() As ObjectId
<BsonElementAttribute("field_1")> _
Public Property FField_1() As Object
End Class
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
I have a very serious issue with EF sending back the wrong data. I know its wrong because I can run the same query against the same table in management studio and get a completely different result.
I did research the problem and found that some people were able resolve the issue by adding:
*DbContextSummary.Refresh(RefreshMode.StoreWins, result);*
When I try adding that I get this error:
The element at index 0 in the collection of objects to refresh has a null EntityKey property value or is not attached to this ObjectStateManager.
After I got that error I tried to do: DbContextSummary.Attach(result) and I received another error.
What is the proper solution and why does this happen?
Relevant Code (without the refresh call):
Private _dbContextSummary As BudgetEntities
Public ReadOnly Property DbContextSummary() As BudgetEntities
Get
If _dbContextSummary Is Nothing Then
_dbContextSummary = New BudgetEntities
End If
Return _dbContextSummary
End Get
End Property
<WebMethod()> _
Public Function GetSummaryData(ByVal month As String, ByVal year As String, ByVal expenseLine As String, ByVal organization As String) As List(Of SummaryModel)
Dim result As List(Of SummaryModel) = Nothing
result = (From s In DbContextSummary.FPRs _
Where s.FY = year _
Where s.Month = month _
Where s.FPRLine = expenseLine _
Where s.VP = organization
Group s By s.MgrID, s.ProgAdm, s.FinanceNumber, s.FinanceNumberName Into g = Group _
Order By g.FirstOrDefault.MgrLastName, g.FirstOrDefault.ProgAdm Ascending
Select New SummaryModel With { _
.Actual = g.Sum(Function(a) a.Actual), _
.Plan = g.Sum(Function(p) p.Plan), _
.YTDActual = g.Sum(Function(ya) ya.YTDActual), _
.YTDPlan = g.Sum(Function(yp) yp.YTDPlan), _
.FinanceNumber = g.FirstOrDefault.FinanceNumber, _
.FinanceNumberName = g.FirstOrDefault.FinanceNumberName, _
.MgrLastName = g.FirstOrDefault.MgrLastName + ", " + g.FirstOrDefault.MgrFirstName, _
.PlanYearTotal = g.FirstOrDefault.PlanYearTotal, _
.ProgAdm = g.FirstOrDefault.ProgAdm _
}).ToList()
Return result
End Function
What is the proper solution and why does this happen?
Simply put, there is no proper solution in your scenario. Refresh is not applicable at all after you have performed a projection (select new) into a type (SummaryModel) that isn't an entity. Your result collection does not contain entities but SummaryModels. You neither can apply Refresh nor Attach to this collection or its elements. Both methods are intended to work with model entities: Refresh updates properties of an already attached entity from the data store and Attach adds an entity to the context in state Unchanged.
I suggest that you open a new question and describe why you think that "EF is sending back the wrong data" and try to solve this problem. It's unlikely that re-loading provides correct data when loading delivers a wrong result.
I'm starting my first Linq to SQL project in VB.NET (which I am also new to).
I am trying to Delete an entity but am having trouble with an InvalidCastException. The debugger breaks at the Next statement in the ForEach loop.
My entity class is called Material.
Any help would be very much appreciated.
Thanks,
Kenneth
Dim materialsTable As Table(Of Material) _
= (New DataContext("Server=.\SQLEXPRESS; Database=Materials; Trusted_Connection=yes;") _
.GetTable(Of Material)())
Dim materialsToDelete = (From x In materialsTable _
Where x.MaterialName = aMaterial.MaterialName _
Select x)
If (materialsToDelete Is Nothing) Then Return
If (materialsToDelete.Count = 0) Then Return
For Each m As Material In materialsToDelete
materialsTable.DeleteOnSubmit(m)
Next
materialsTable.Context.SubmitChanges()
Make sure you actually run the query with a .ToList()
Also, go with a straightforward DataContext if you can. I've not seen your implementation of the DC anywhere.
Dim db as new NorthwindDataContext()
Dim materialsToDelete = (From x In db.Materials _
Where x.MaterialName = aMaterial.MaterialName _
Select x)
You actually don't need to loop to delete them.
materialsTable.DeleteAllOnSubmit(materialsToDelete)
materialsTable.Context.SubmitChanges()
Dim tenItem = From t In _InvalidFeeList _
From i In ItemCount _
Where t.FeeCode <> i.FeeCode _
Order By t.Description _
Ascending Take (10)
Dim feeList As List(Of AccessorialFee) = tenItem.ToList()
I am getting "Can not convert to System.generic.list" error. I look all over for this error and it seem like my code should work for example here
I don't get it. Can someone tell me where i got it wrong?
edit: I think i should explain what I'm trying to do here. I want to compare two object list and select the object from the InvalidFeeList if the FeeCode is not equal to the object in ItemCount FeeCode and take the first 10 objects from the InvalidFeeList.
The problem is that you've got two "From" clauses, so the result isn't just the type of the original collection. It's easy to fix though - just add a projection at the end:
Dim tenItem = From t In _InvalidFeeList _
From i In ItemCount _
Where t.FeeCode <> i.FeeCode _
Order By t.Description _
Ascending Take (10) _
Select t ' This is the new line '
Dim feeList As List(Of AccessorialFee) = tenItem.ToList()
EDIT: Are you trying to find items in _InvalidFeeList whose FeeCode isn't present in any item in ItemCount? If so, I suggest this change:
Dim feeCodes = From i In ItemCount Select i.FeeCode
Dim feeCodeSet = new HashSet(Of FeeCodeType)(feeCodes)
Dim tenItem = From t in _InvalidFeeList
Where Not feeCodeSet.Contains(t.FeeCode)
Order By t.Description _
Ascending Take (10)
Dim feeList As List(Of AccessorialFee) = tenItem.ToList()
As you can see, I didn't know the type of FeeCode, and VB is not exactly my strong point, but I hope you get the general idea. This suggestion is assuming you're using LINQ to Objects - if you're using LINQ to SQL I'm not sure of the best way to do it. Note that we no longer need the Select clause for tenItem as we're only dealing with a single collection now.
_InvalidFeeList is not of type List(Of AccessorialFee)
[Edit] Try this and add a breakpoint and a watch:
Dim tenItem = (From t In _InvalidFeeList _
From i In ItemCount _
Where t.FeeCode <> i.FeeCode _
Order By t.Description _
Ascending Take (10)).ToList().GetType()