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.
Related
I've got a list of objects
Class Bundledtellingen
Property tTimestamp As String
Property tValue As Double
End Class
Now I am trying to group this list by tTimestamp and sum tValue. By searching similar questions it was clear the best way to go is using Linq. I've put this together:
Dim query = bundledlist.GroupBy( _
Function(telling) telling.tTimestamp, _
Function(telling) telling.tTimestamp, _
Function(ts, values) New With _
{.Key = ts, _
.Sum = values.Sum()} _
)
Using writer As StreamWriter = New StreamWriter("C:\test.txt")
For Each result In query
writer.WriteLine(result.Key & " " & result.Sum)
Next
End Using
As far as I can tell by looking at the examples at http://msdn.microsoft.com/en-us/library/bb534493.aspx#Y0 this should work, though i get the following exception: "Overload resolution failed because no accessible 'Sum' accepts this number of arguments."
You've specified one unnecessary parameter into your GroupBy call. Thy that one:
Dim query = bundledlist.GroupBy( _
Function(telling) telling.tTimestamp, _
Function(ts, values) New With _
{.Key = ts, _
.Sum = values.Sum()} _
)
The first one is key selector, the second is result selector.
Your call with 3 parameters has additional value selector, where you're selecting Function(telling) telling.tTimestamp twice - once for Key and once for Value. That's why your Sum didn't work: you tried call Sum on telling.tTimestamp.
I'm pretty stuck on this anonymous type from LINQ business. It's a consequence of working through an answer to a previous question, but sadly I just havent the brain power to get this to work at all.
I'm returning a limited list of events that are connected to each person. The source is Entity Framework where I'm still battling to get criteria limited results from a navigation property. The code below is my translation from Nicholas Butler's answer. However, I can't find any way to adapt the anonymous type. Casts don't seem to work - or I just haven't a clue (likely). Can anyone help please?
Dim test = context.persons.Where(Function (r) r.personActive).Select(Function (o) New With { _
.person = o, _
.events = o.events.Where( Function(e) e.eventDateTime > startdate) _
})
Dim Res = New ObservableCollection(Of person )
For Each person In test
Res.Add(person)
Next
Gives me:
Error 2 Value of type '<anonymous type> (line 53)' cannot be converted to 'PersonEntity.person'. E:\Dropbox\Work Experimental\PersonEntity- Copy\PersonEntity\personRepository.vb 61 29 PersonEntity
I've gotten further with this code but I still cannot have the attached events as I get yet another error with the casting, this time of events. Generic List to ObservableList doesn't convert apparently. It seems an incredible way round to answer my original question!
Dim test = context.persons.Where(Function(r) r.personActive).Select(Function(o) New With { _
.person = o, _
.events = o.events.Where(Function(e) e.eventDateTime > startdate) _
})
Dim Res = New ObservableCollection(Of person)
For Each t In test
Dim r As New person
r = t.person
r.events = t.events
Res.Add(r)
Next
Return Res
Function(o) New With { _
.person = o, _
.events = o.events.Where(Function(e) e.eventDateTime > startdate) _
}
This returns an anonymous type, not a Person. Did you mean to Add its person property*?
For Each o In test
Res.Add(o.person)
Next
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
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()
Stupid nHibernate noob question, but I can't find the answer anywhere ...
I have a "product" class successfully mapped to a product table, and an "sku" class. Sku is a child object of "product" and the two tables in the DB are related by primary key.
So far all the basic nHibernate stuff works - I can run CRUD opeations against the databasse successfully. I can make expression based queries successfully, as in ...
Dim results As ArrayList = session.CreateCriteria(Of DataTransferObjects.Product) _
.Add(Expression.Like("Name", nameSearchString)) _
.List()
.. And the result is a list of product objects which successfully expose the expected Sku child objects. However, if I try the above code searching on field names from the Sku table, NHibernate throws an error:
Dim results As ArrayList = session.CreateCriteria(Of DataTransferObjects.Product) _
.Add(Expression.Like("SkuCode", skuSearchString)) _
.List()
Results in "could not resolve property: SkuCode of: Product"
This works:
Dim results As ArrayList = session.CreateCriteria(Of DataTransferObjects.Sku _
.Add(Expression.Like("SkuCode", skuSearchString)) _
.List()
But, unsurprisingly, it only returns Sku objects whereas I need the product object.
This also compiles:
Dim results As ArrayList = session.CreateCriteria(Of DataTransferObjects.Product) _
.Add(Expression.Like("Name", nameSearchString)) _
.CreateCriteria("Skus").Add(Expression.Like("SkuCode", skuSearchStrung)) _
.List()
But it returns nothing at all, even though the first expression is valid
How can I run an Expression.Like against fields in the Sku table?
I've solved this - thought I'd leave it here for anyone else to discover. This sort of thing seems very poorly documented:
Dim results As ArrayList = session.CreateCriteria(Of DataTransferObjects.Product) _
.CreateAlias("Skus", "sku") _
.Add(Expression.Or( _
Expression.Like("Name", nameSearchString), _
Expression.Like("sku.SkuCode", skuSearchStrung))) _
.List()
I've blogged about my frustrations with this framework:
http://mattthr.blogspot.com/2010/02/quey-across-join-in-nhibernate.html