 |
| ASP.NET 3.5 Professionals If you are an experienced ASP.NET programmer, this is the forum for your 3.5 questions. Please also see the Visual Web Developer 2008 forum. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the ASP.NET 3.5 Professionals 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
|
|
|
|

July 1st, 2008, 12:10 PM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
|
|
Imar,
THANK YOU!!
Yes, I did try various Google searches and MSDN. I guess the entire reason I was confused is because I always understood DataKeys to represent your primary key - it was your comment above about using it to get to the "non primary key" "userID" field that confused me - it made me think that you could use it for other purposes (such as simply wanting access to it without tying it to a control).
You are right - I originally thought about tying the memberID to the userID from the membership table - but ran into problems assimilating it into your 3-tier model because of it being a GUID (I'm sure I could find work-arounds - it just seemed easier to create my own key).
At the end of the day, I just wish there was an easier way to tie to fields rather than binding them to hidden fields - only to make it easier to work with them in code - behind pages so that ... for example, if I wanted to get access to the "IsApproved" Boolean in the MembershipTable--right now, it's bound to a hidden field and I have to reference it that way.
Again - was only thrown off because I misunderstood your suggestion above (using DataKeys) was a solution to getting to these fields.
I *really* appreciate your help!
Sincerely,
Rob
|
|

July 1st, 2008, 01:45 PM
|
 |
Friend of Wrox
|
|
Join Date: Aug 2003
Posts: 5,407
Thanks: 0
Thanked 16 Times in 16 Posts
|
|
Rob,
I would dissagree a bit with Imar about "abusing the keys". The repeating controls that have the DataKeys field don't really care what the meaning of the data is. The property is simply there so you can store needed data without having to put it into the control (i.e. in the form or a hidden column, hidden field, etc.). I would say that it is perfectly OK to put multiple columns, possibly unrelated or non-key columns in there. It won't break anything. You just need to know how to use the data on the other side of a postback. If you have one or more columns worth of data as the actual row key (simple or compound key) as well as other data, the control won't care. You can use the key value(s) for database query filter criteria and use the others values for whatever.
What problems did you have "assimilating" the userID guid with the multi layer approach? A Guid type isn't any less portable than any other "simple" row key type such as an int. Was the problem simply with the way Guids can be treated as strings?
-Peter
compiledthoughts.com
|
|

July 1st, 2008, 05:25 PM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
|
|
Peter,
Wow--sorta confused now - but it's completely because I don't understand how DataKeys works--and, contrary to popular belief - I have done quite a bit of research - more than the several links Imar put - but none of them give examples of using more than one DataKeyField.
So---here's where my confusion stems from--really in not knowing how things work in the "black box"
a) When you set a DataKeyField--"somehow" when you do updates or deletes, the control knows to pass the value you put in the DataKeyField in for the primary key. So--my first question is--will that get screwed up if you have more than one datakeyfield.
b) How do you reference the other datakey in the behind the scenes page..for example:
Dim someVariable = DetailsView.datakey(e.itemindex)
(not at my development computer, so I know I butchered that--but if I have two datakeyfields, how do I reference one from the other in the code behind? Again-I have been unable to find examples.
Really--at the end of the day--all I want to know how to do is reference fields that are returned from my object without having to bind them to a control (hidden or otherwise). I'd like an example of how to do this - using more than one datakey. Secondly, will having more than one datakeyfield mess with the fact that all websites - MSDN - google, etc - say that the datakeyfield is for the primary key-will the control's update/delete behavior be screwed up?
Sorry to belabor this point - but it's just one thing that I never did fully understand and all the research I have done online doesn't really attest to how it works--they simply give easy examples showing one datakeyfield and they *all* just reference one field.
Thanks Peter
Rob
|
|

July 2nd, 2008, 12:55 PM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
|
|
Hi Peter,
I agree with you, you can use the DataKeys for items that are not necessarily part of the primary key. My bad.
Rob: that is so easy to find out once you know where to look:
1. Add a GridView to your page
2. Hook it up to a SqlDataSource that supports editing
3. Hook into the GridView1_RowUpdating event.
4. Set a breakpoint in the (possibly) empty handler for GridView1_RowUpdating
5. Run the page, edit a record and choose Update.
6. The breakpoint will be hit.
7. Add the following to your Watch window:
GridView1.DataKeys[e.RowIndex]
8. Notice how that results in an object of type System.Web.UI.WebControls.DataKey
9. Change the code in the Watch window so it casts the DataKeys to a DataKey:
((System.Web.UI.WebControls.DataKey) GridView1.DataKeys[e.RowIndex])
10. Notice how this object now has a Values collection. Expand it and you'll see what it contains.
11. Manually add a Watch for:
((System.Web.UI.WebControls.DataKey) GridView1.DataKeys[e.RowIndex]).Values[0]
((System.Web.UI.WebControls.DataKey) GridView1.DataKeys[e.RowIndex]).Values[1]
Notice how [0] and [1] contain the values for your first and second DataKey fields.
Hope this helps,
Imar
---------------------------------------
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Everyone is unique, except for me.
Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004
Want to be my colleague? Then check out this post.
|
|

July 2nd, 2008, 01:30 PM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
|
|
Imar,
A couple things with this - and not sure if this matters, but I am using a DataList.
a) When i try, in the control, putting DataKeyField="memberID,userID" as a property and then run the app, I get an error that says "Databinding: "Namepace.Bo.Member" does not contain a property with the name 'memberID,userID'--so I'm getting stuck simply by trying to assign it in the control
b) In the code behind, when I try typing (keep in mind I'm using VB-again, not sure if matters) : DataList1.DataKeys(e.item.itemindex) it doesn't give me intellisense to put another "." to reference another array.
c) If I use multiple keys will the control still work--the reason I ask this is my experience in the past was that you set up the datakeyfield to that which is your primary key and then updates/deletes magically work (again, I don't understand what is happening in the black box).
I am genuinely trying everything you're telling me to do - just not getting the same results.
|
|

July 2nd, 2008, 01:36 PM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
|
|
Don't use DataKeyField, use DataKeys instead.
In VB, use CType like you normally would to do a proper cast like this:
(CType(GridView1.DataKeys(e.RowIndex), System.Web.UI.WebControls.DataKey)
and
(CType(GridView1.DataKeys(e.RowIndex), System.Web.UI.WebControls.DataKey).Values
You won't get IntelliSense with a proper cast; sometimes you need to think for yourself and not purely reply on IntelliSense.... ;)
Do yourself a favor: try this with a simple SqlDataSource first (you weren;t doing exactly as I was telling you ;-0 ) so you understand the concepts. Then move on to an ObjectDataSurce.
Cheers,
Imar
---------------------------------------
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Everyone is unique, except for me.
Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004
Want to be my colleague? Then check out this post.
|
|

July 2nd, 2008, 01:48 PM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
|
|
Imar,
Man--I am certainly not trying to annoy - and I am feeling very stupid here..but, please keep in mind this is a DataList (not sure if that matters). In the control itself (ie <asp:Datalist ID="DataList1.... /> "DataKeys" is not a property - only DataKeyField. When I do:
<asp:DataList id="DataList1" runat="server" .... DataKeyField="memberID,userID"> I get the error I mentioned. So I can't even get to the point of referring to it in code behind.
|
|

July 2nd, 2008, 02:30 PM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
|
|
Can you please stop apologizing for everything you say or do and stop feeling stupid? It's starting to look quite silly. If I thought for a split second you'd be annoying me on purpose, I'd simply stop answering your questions. So, as long as you keep getting replies you're pretty safe. And if you say sorry for apologizing, I am outta here.
Anyway, to understand the concepts, follow my steps. My steps say to use a GridView, not a DataList. Once you understand the concepts and the basics, move on.
One direction to move on is to use a ListView instead of a DataList as it supports multiple keys using DataKeyNames (sorry I didn't make that clearer earlier). The ListView not really replaces the DataList officially, but in many respects offers a lot more functionality.
You can use DataKeyNames for the comma separated list of fields. The rest of the code is pretty much the same:
<asp:ListView ID="ListView1" runat="server" DataKeyNames="Col1, Col2" DataSourceID="SqlDataSource1" ...>
Debugging in code behind for ItemEditing:
((System.Web.UI.WebControls.DataKey) ListView1.DataKeys[e.NewEditIndex]).Values[0]
((System.Web.UI.WebControls.DataKey) ListView1.DataKeys[e.NewEditIndex]).Values[1]
Hope this helps,
Imar
---------------------------------------
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Everyone is unique, except for me.
Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004
Want to be my colleague? Then check out this post.
|
|

July 2nd, 2008, 06:56 PM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
|
|
Imar,
Understand on the apology.
I just ran your example with a GridView - and I see it working - and it works fine. In fact, all of the examples in MSDN and Google show Gridview. My entire problem is/was that I am using a DataList - and the syntax isn't the same. Datalist uses "DataKeyField" as a property of the control on the regular .aspx page. Whenever I put a comma-seperated list (ex. "DataKeyField='memberID, userID'") I get the error "DataBinding: 'Searing.Sprint.CustomerAdvocacy.BO.Member' does not contain a property with the name 'memberID, userId'." Consequently, when I leave it with one and simply try referring to it in the codebehind page in the DataList1_ItemCommand function, it doesn't appear as if multiple DataKeys are supported - all I can do is DataList1.DataKeys(e.item.itemindex) - and have played around with it to see if there is a way to support a multi-dimension array - you can't.
So - it appears - that DataList doesn't support multiple keys - which is what I was asking all along.
Added to that is my confusion (and I can't for the life of me remember what) as to the purpose of the DataKeyField (DataKeyName) when you leave it alone for use as a Primary Key - I think it was so that, if selected, it refered to the DataKey as the value? I don't know - whatever the reason (as I'm confused right now) I didn't know if multiple keys in the DataKeyNames would mess up this relationship.
I'm just going to drop this and just use the HiddenField that's working - was simply trying to get away from binding to controls in a DataList - doesn't seem like I can do that with a DataList - must use GridView or ListView.
Thanks,
Rob
|
|

July 2nd, 2008, 09:24 PM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 238
Thanks: 0
Thanked 2 Times in 2 Posts
|
|
Ok, perhaps this might help me out. I followed Imar's example - using a GridView and a simple SQLDataSource to tie to my Member Table. When I have the property in the GridView of DataKeyNames="memberID,userID" it works (updates) however, when I remove it - I get an error "Implicit conversion from data type sql_variant to uniqueidentifier is not allowed. Use the CONVERT function to run this query." (when attempting an update). When attempting a Delete I get "Must declare the scalar variable "@memberID". "
(**Even more confusing is that when I put multiple values in the DataKeyNames field - it pulls out the right one for the SQL statement...thoroughly confused on how this is all working)
Below is my code.
So my question then is:
a) Why am I getting that error
b) This is a *perfect* example of where messing with DataKeyNames messes with the simple update or delete - I guess I'm confused on how the 'black box' works to pass parameters--you have <asp:parameters> in the update that somehow find their values - except for the one being used for primary key?
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1">
<Columns>
<asp:CommandField ShowEditButton="True" ShowSelectButton="True"
ShowDeleteButton="True" />
<asp:BoundField DataField="memberID" HeaderText="memberID"
InsertVisible="False" ReadOnly="True" SortExpression="memberID" />
<asp:BoundField DataField="userID" HeaderText="userID"
SortExpression="userID" />
<asp:BoundField DataField="fName" HeaderText="fName" SortExpression="fName" />
<asp:BoundField DataField="lName" HeaderText="lName" SortExpression="lName" />
<asp:BoundField DataField="phone" HeaderText="phone" SortExpression="phone" />
<asp:BoundField DataField="mobPhone" HeaderText="mobPhone"
SortExpression="mobPhone" />
<asp:BoundField DataField="workLocationID" HeaderText="workLocationID"
SortExpression="workLocationID" />
<asp:BoundField DataField="positionID" HeaderText="positionID"
SortExpression="positionID" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [memberID], [userID], [fName], [lName], [phone], [mobPhone], [workLocationID], [positionID] FROM [Members]"
DeleteCommand="DELETE FROM [Members] WHERE [memberID] = @memberID"
InsertCommand="INSERT INTO [Members] ([userID], [fName], [lName], [phone], [mobPhone], [workLocationID], [positionID]) VALUES (@userID, @fName, @lName, @phone, @mobPhone, @workLocationID, @positionID)"
UpdateCommand="UPDATE [Members] SET [userID] = @userID, [fName] = @fName, [lName] = @lName, [phone] = @phone, [mobPhone] = @mobPhone, [workLocationID] = @workLocationID, [positionID] = @positionID WHERE [memberID] = @memberID">
<DeleteParameters>
<asp:Parameter Name="memberID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="userID" Type="Object" />
<asp:Parameter Name="fName" Type="String" />
<asp:Parameter Name="lName" Type="String" />
<asp:Parameter Name="phone" Type="String" />
<asp:Parameter Name="mobPhone" Type="String" />
<asp:Parameter Name="workLocationID" Type="Int32" />
<asp:Parameter Name="positionID" Type="Int32" />
<asp:Parameter Name="memberID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="userID" Type="Object" />
<asp:Parameter Name="fName" Type="String" />
<asp:Parameter Name="lName" Type="String" />
<asp:Parameter Name="phone" Type="String" />
<asp:Parameter Name="mobPhone" Type="String" />
<asp:Parameter Name="workLocationID" Type="Int32" />
<asp:Parameter Name="positionID" Type="Int32" />
</InsertParameters>
</asp:SqlDataSource>
|
|
 |