 |
BOOK: Beginning ASP.NET 4.5 : in C# and VB
 | This is the forum to discuss the Wrox book Beginning ASP.NET 4.5: in C# and VB by Imar Spaanjaars; ISBN: 978-1-118-31180-6 |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the BOOK: Beginning ASP.NET 4.5 : in C# and VB section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|
|

November 27th, 2013, 11:19 PM
|
|
Authorized User
|
|
Join Date: Dec 2011
Posts: 86
Thanks: 20
Thanked 3 Times in 3 Posts
|
|
A little More
Actually this gets ignored also by TryUpdateModel:
Code:
items.SectorTitle = String.Concat(sector.SectorTitle, " sometext")
It doesn't seem to matter what you try to change in the data, either what came from the listview or from the DB, TryUpdateModel is going to update the database with whatever originally came from listview. Unless there is some other way to tap into this model.
With a regular Try-catch this is not a problem. At least I'm not seeing what problem could be caused by NOTusing TryUpdateModel?
|
|

November 28th, 2013, 03:09 PM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
|
|
Take a look at this:
Code:
sector.SectorTitle += "sometext"
TryUpdateModel(items)
You're updating the title of the item from the database before you call TryUpdateModel. This means your changes get lost. TryUpdateModel has no idea what the original(database) values were and simply copies whatever came from the form into the entity, overwriting database values as well as values you set manually.
Simply change the order of these two lines and it should work.
Cheers,
Imar
|
|
The Following User Says Thank You to Imar For This Useful Post:
|
|
|

November 28th, 2013, 09:19 PM
|
|
Authorized User
|
|
Join Date: Dec 2011
Posts: 86
Thanks: 20
Thanked 3 Times in 3 Posts
|
|
Finally!
Quote:
Originally Posted by Imar
change the order of these two lines
|
Code:
Public Sub ListView1_UpdateItem(sector As Sector)
Dim items As Sector = Nothing
items = (From s In myentity.Sectors
Where s.SectorId = sector.SectorId
Select s).Single()
If items Is Nothing Then
msglabel.Text = " Failed"
Return
End If
' if you try change either "Sector" or "items" before this point, the changes are ignored
TryUpdateModel(items)
' edit/manipulate user input at this point
' sector.SectorTitle += " test" But just changing "Sector" here doesn't change DB
items.SectorTitle = String.Concat(sector.SectorTitle, " test") ' A change to "items" here goes to DB
If ModelState.IsValid Then
myentity.SaveChanges()
msglabel.Text = " Successful"
Else
msglabel.Text = " Fail"
End If
End Sub
Of course you are correct and now it's easy to see how this works. One little twist - it doesn't appear you can change what is coming from listview directly, but you can push changes into the DB fields (items) right before the DB changes are saved.
Perhaps I'm old school, but I recall when MS would have been more inclined to explain concepts like this with simple flow charts and graphical representations. From my POV, this whole discovery process could have been far less time consuming if MS provided an overview chart showing how the parts and pieces of this fit together - it seems pretty simple to envision once you know how this actually works.
Also, the tutorial you found is pretty hard to follow for a VB person - and the sample VB code is a mess. I've asked the author about VB but no response. I did a lot of searching on MS and MSDN sites and found almost nothing to explain this EF6 - Web Controls architecture or VB examples.
We need your book! And, thanks again for your help. BTW, please let me know if this last code sample is satisfactory enough for a last update on SO.
|
|

November 29th, 2013, 06:34 PM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
|
|
Hi Dave.
The Sector parameter isn't used, and therefore changes made to it aren't applied. The TryUpdateModel gets its data from the control. You would use the Sector parameter if you do custom mapping, for example manually or with a framework like AutoMapper.
Your code looks fine as-is, although I would make a few changes to improve readability:
Code:
Public Sub ListView1_UpdateItem(sector As Sector)
Dim item As Sector = (From s In myContext.Sectors
Where s.SectorId = sector.SectorId
Select s).SingleOrDefault()
If item Is Nothing Then
msglabel.Text = " Failed"
Return
End If
TryUpdateModel(item)
item.SectorTitle = String.Concat(sector.SectorTitle, " test") ' A change to "items" here goes to DB
If ModelState.IsValid Then
myContext.SaveChanges()
msglabel.Text = " Successful"
Else
msglabel.Text = " Fail"
End If
End Sub
I renamed items to item because it's a single instance and combined the declaration and instantiation on a single line. I also renamed the DbContext to myContext as myentity implies a single entity instead of a DbContext providing access to multiple entities.
This is pure naming though; the original code hasn't been changed.
I also changed Single() to SingleOrDefault() for case where the sector no longer exists. Single() will always return an instance, or crash if the item doesn't exist so the check for Is Nothing isn't needed. As an alternative, you could use Single() (if you're sure the item always exists), remove the check for Nothing and implement a Try Catch block for cases where the Sector doesn't exist.
Cheers,
Imar
Last edited by Imar; November 30th, 2013 at 05:34 AM..
|
|
The Following User Says Thank You to Imar For This Useful Post:
|
|
|

November 29th, 2013, 08:32 PM
|
|
Authorized User
|
|
Join Date: Dec 2011
Posts: 86
Thanks: 20
Thanked 3 Times in 3 Posts
|
|
Amen
Thanks again, Imar, your edits are much appreciate. The wording changes not only help the documentation value but also make the overall concepts clearer.
I put in an equal sign "Dim item As Sector = (From s In myContext.Sectors" and posted this final version on SO - hopefully, it'll help someone else struggling with this.
http://stackoverflow.com/questions/2...w-selectmethod
BTW, I just bought another copy of this 4.5 book for my daughter who was having problems with the security model - I'm sure it'll help her. But, now she'll expect me to get her a copy of the 4.5.1 book!
|
|

November 30th, 2013, 05:36 AM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
|
|
Quote:
|
I put in an equal sign "Dim item As Sector = (From s In myContext.Sectors"
|
Ah, yes, I missed that. Thanks; I also updated my code example.
Quote:
|
BTW, I just bought another copy of this 4.5 book for my daughter who was having problems with the security model - I'm sure it'll help her. But, now she'll expect me to get her a copy of the 4.5.1 book!
|
Great; hope she likes it. The new book will be out around March I think...
Imar
|
|

December 8th, 2013, 10:47 PM
|
|
Authorized User
|
|
Join Date: Dec 2011
Posts: 86
Thanks: 20
Thanked 3 Times in 3 Posts
|
|
ef6 linq selectmethod with user parameter
Hi Imar,
I've been trying to put together my "tool kit" of methods for working with Gridview and Listview in VS2013/EF6 - and encountered a few frustrations. I don't want to keep pestering you so I've tried to research issues the best I can. It appears I may have solved my latest challenge, but perhaps you could take a look at this post and see if makes sense to you:
Select with filter and sort
Thanks
|
|

December 9th, 2013, 08:36 AM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
|
|
Are you perhaps using the DynamicQuery library? Otherwise, I can't see how Sort(string) could work....
Cheers,
Imar
|
|

December 9th, 2013, 10:55 AM
|
|
Authorized User
|
|
Join Date: Dec 2011
Posts: 86
Thanks: 20
Thanked 3 Times in 3 Posts
|
|
Dynamic or Not
Quote:
|
Originally Posted by Imar
Are you perhaps using the DynamicQuery library? Otherwise, I can't see how Sort(string) could work....
|
My bin only has entityframework.dll and entityframework.sqlserver.dll and my packages.config only shows entityframework 6.0, I didn't install any other NuGet packages and my VB code only imports schoolentities and system.linq. So, it's not clear to me that I could be using a special DynamicQuery library?
As I stumbled around trying to find a simple solution to this problem, I found lots of Dynamic Query code examples that were way above my paid grade and I didn't want to get that far into the weeds with this.
It became clear that as soon as I did the filter thing with "Select New With..." that I entered the anonymous type world and returning data to the grid did not work the same - for one thing, "AllowingSort" no longer worked. I couldn't find a simple way to change the sort column using "Dynamic" coding ideas. So, I went down the path of manipulating the list with the "Sortby" thing. I assumed this had nothing to do with "Dynamic" and was a normal feature of VB or linq. I can assure you that the grid sorts perfectly.
If you're curious the little test DB and view (used in the program) looks like this (with foreign keys) - of course you'd have to generate the entity framework model and put some data in the tables.
Code:
CREATE TABLE [dbo].[Student](
[StudentId] [int] IDENTITY(1,1) NOT NULL,
[StudentName] [varchar](50) NOT NULL,
[Birth] [date] NULL,
CREATE TABLE [dbo].[Course](
[CourseNo] [int] IDENTITY(1,1) NOT NULL,
[CourseName] [nchar](10) NOT NULL,
CREATE TABLE [dbo].[Enrollment](
[EnrollNo] [int] IDENTITY(1,1) NOT NULL,
[StudentNo] [int] NOT NULL,
[CourseId] [int] NOT NULL,
CREATE VIEW [dbo].[EnrollStudentCourse]
AS
SELECT dbo.Student.StudentName, dbo.Course.CourseName, dbo.Enrollment.EnrollNo, dbo.Course.CourseNo, dbo.Student.StudentId
FROM dbo.Course INNER JOIN
dbo.Enrollment ON dbo.Course.CourseNo = dbo.Enrollment.CourseId INNER JOIN
dbo.Student ON dbo.Enrollment.StudentNo = dbo.Student.StudentId
Code:
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
selectmethod="GridView1_GetData"
AllowSorting="True">
<Columns>
<asp:BoundField DataField="StudentName" HeaderText="StudentName" SortExpression="StudentName" />
<asp:BoundField DataField="CourseName" HeaderText="CourseName" SortExpression="CourseName" />
<asp:BoundField DataField="CourseNo" HeaderText="CourseNo" ReadOnly="True" SortExpression="CourseNo" />
<asp:BoundField DataField="StudentId" HeaderText="StudentId" ReadOnly="True" SortExpression="StudentId" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
Code:
Imports SchoolEntities
Imports System.Linq
Partial Class _Default
Inherits System.Web.UI.Page
Public Function GridView1_GetData(ByVal sortbyexpression As String) As IEnumerable
Dim dbcontext As New SchoolEntities()
Dim namesearch As String = "Joe" 'user could pick from some list
If (sortbyexpression = Nothing) Then
sortbyexpression = "studentname"
End If
Dim mylist = From s In dbcontext.EnrollStudentCourses
Where s.StudentName = namesearch
Select (New With {s.CourseName, s.CourseNo, s.StudentId, s.StudentName})
mylist = mylist.SortBy(sortbyexpression)
Return mylist.ToList()
End Function
End Class
Hopefully, my code is not violating something and could be unstable - this is why I posted it.
|
|

December 11th, 2013, 11:06 AM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
|
|
Oh, I see now. You're using SortBy, not OrderBy. OrderBy doesn't support sorting on a string and requires the DynamicQuery library.
One thing to be aware of with this code: all records are always retrieved from the table which may cause issues if the table has a large number of records.
Cheers,
Imar
|
|
The Following User Says Thank You to Imar For This Useful Post:
|
|
|
 |
|