.NET Forum / Languages / C# / February 2008
ObjectDataSource and Linq. Please, help! I don't know what else to try. Thank You.
|
|
Thread rating:  |
shapper - 22 Feb 2008 02:57 GMT Hello,
I used a "Linq to SQL classes" in VS 2008 to map the tables of a database: MyDbDataContext
One of the tables is named Tags and has 2 columns: TagID and Text. This table is related to a second table named Articles through a table ArticlesTags.
I would like to use an ObjectDataSource as a layer between my data and a ListView.
In my page I created the following:
private void odsTags_Init(object sender, EventArgs e) { odsTags.ID = "odsTags"; odsTags.SelectMethod = "GetTags"; odsTags.TypeName = "MyDbDataContext"; }
public static ICollection GetTags() { MyDbDataContext database = new MyDbDataContext(); var query = from t in db.Tags select new { TagId = t.TagId, TagText = t.TagText, Active = t.ArticlesTags.Any }; return tags; }
I get the following error: ObjectDataSource 'odsTags' could not find a non-generic method 'GetTags' that has no parameters.
I have no idea what I am doing wrong. I am not able to solve it! I tried to Google for a solution but I didn't find it. I don't know what I am doing wrong.
This is the first time I use an ObjectDataSource with a Linq DataContext.
Thanks, Miguel
Jon Skeet [C# MVP] - 22 Feb 2008 07:40 GMT > I used a "Linq to SQL classes" in VS 2008 to map the tables of a > database: MyDbDataContext [quoted text clipped - 27 lines] > return tags; > } That's not your actual code - note the value returned from GetTags().
> I get the following error: > ObjectDataSource 'odsTags' could not find a non-generic method > 'GetTags' that has no parameters. Is your type name really just MyDbDataContext with no namespace? That's the first thing to try.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet World class .NET training in the UK: http://iterativetraining.co.uk
shapper - 22 Feb 2008 15:53 GMT > > I used a "Linq to SQL classes" in VS 2008 to map the tables of a > > database: MyDbDataContext [quoted text clipped - 40 lines] > Jon Skeet - <sk...@pobox.com>http://www.pobox.com/~skeet Blog:http://www.msmvps.com/jon.skeet > World class .NET training in the UK:http://iterativetraining.co.uk Yes, it is my code!
I just did a mistake when converting from VB.NET, which I am using for this example, to C#.
I now create a sample which is only a web site with Sample.Aspx and LabDataContext.
I always get the same error ...
Could someone please provide me a work example. I am going crazy.
The only way I was able to make this work was doing the following:
I placed the GetTags inside "Extensibility Method Definitions" region in LabDataContext class using the following:
<DataObjectMethodAttribute(DataObjectMethodType.Select, True)> _ Public Shared Function GetTags() As IQueryable Dim database As New LabDataContext Dim tags = From t In database.Tags _ Select t.TagID, _ t.Text, _ Active = t.ArticlesTags.Any Return tags End Function ' GetTags
Now I get the following error:
ListView with id 'ListView1' must have a data source that either implements ICollection or can perform data source paging if AllowPaging is true.
Then I changed to:
<DataObjectMethodAttribute(DataObjectMethodType.Select, True)> _ Public Shared Function GetTags() As ICollection Dim database As New LabDataContext Dim tags = From t In database.Tags _ Select t.TagID, _ t.Text, _ Active = t.ArticlesTags.Any Return tags.ToList End Function ' GetTags
Now it works but I am not sure if this is the right way to do this. Any idea? I would prefer to have the GetTags methods outside the DataContext.
Finally, I tried to add a DeleteMethod to my ObjectDataSource:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetTags" DeleteMethod="DeleteTag" TypeName="LabDataContext"> <DeleteParameters> <asp:Parameter Type="Object" Name="Tag"></asp:Parameter> </DeleteParameters> </asp:ObjectDataSource>
And I get the following error:
ObjectDataSource 'ObjectDataSource1' could not find a non-generic method 'DeleteTag' that has parameters: Tag, TagID.
I am using the "Tag" delete parameter because I was thinking in using the default method inside "Extensibility Method Definitions" region in LabDataContext class:
Partial Private Sub DeleteTag(ByVal instance As Tag) End Sub
I have been Goggling for information on how to implement ObjectDataSource with a Linq to SQL classes but until now I wasn't able to find anything.
Could someone, please, advise me on the issues I just posted.
Thank You,
Miguel
Jon Skeet [C# MVP] - 22 Feb 2008 16:04 GMT > Yes, it is my code! > > I just did a mistake when converting from VB.NET, which I am using for > this example, to C#. Then it's not your code - your code is the VB.NET code.
You presented us code which wouldn't compile. As you told us about something failing *other* than compilation, that means the code you presented wasn't the code you were trying to use.
<snip>
> Now I get the following error: > > ListView with id 'ListView1' must have a data source that either > implements ICollection or can perform data source paging if > AllowPaging is true. Do you require paging?
> Then I changed to: > [quoted text clipped - 11 lines] > Any idea? > I would prefer to have the GetTags methods outside the DataContext. So put it outside the DataContext - I'm afraid I don't see the problem with doing so.
> Finally, I tried to add a DeleteMethod to my ObjectDataSource: > [quoted text clipped - 17 lines] > Partial Private Sub DeleteTag(ByVal instance As Tag) > End Sub Unless I'm mistaken, you've told ASP.NET to try to find a method with a parameter of type Object, not of type Tag. However, at this point it's really an ASP.NET question more than LINQ - the LINQ side of things is reasonably irrelevant. You might want to ask on the ASP.NET newsgroup - particularly as there are more likely to be VB developers there than here.
Jon
shapper - 22 Feb 2008 16:33 GMT > > Yes, it is my code! > [quoted text clipped - 66 lines] > > Jon Hi Jon,
The moment I put it outside the DataContext I get the error: ObjectDataSource 'ObjectDataSource1' could not find a non-generic method 'GetTags' that has no parameters.
This is what is driving me crazy. I really don't see any reason why this does not work.
Yes I need paging and that was why I am return the tags as a Collection.
It is irrelevant to me if the help is in VB.NET or C#. I write in VB.NET only because it is faster to me.
Here is my entire code. Maybe someone can see if I am doing something wrong (I converter everything to C#):
MyPage.ASPX
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="ListViewDesign.aspx.vb" Inherits="ListViewDesign" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>List View Design</title> </head> <body> <form id="fListViewDesign" runat="server"> <asp:ListView ID="ListView1" runat="server" DataSourceID="ObjectDataSource1" DataKeyNames="TagID" InsertItemPosition="FirstItem"> <AlternatingItemTemplate> <tr style=""> <td> <asp:Label ID="TagText" runat="server" Text='<%# Eval("Text") %>' /> </td> <td> <asp:LinkButton ID="EditButton" runat="Server" Text="Edit" CommandName="Edit" /> <asp:LinkButton ID="DeleteButton" runat="Server" Text="Delete" CommandName="Delete" /> </td> </tr> </AlternatingItemTemplate> <LayoutTemplate> <table runat="server"> <tr runat="server"> <td runat="server"> <table id="itemPlaceholderContainer" runat="server" border="0" style=""> <tr runat="server" style=""> <th runat="server"> Tag Text </th> <th runat="server"> Command </th> </tr> <tr id="itemPlaceholder" runat="server"> </tr> </table> </td> </tr> <tr runat="server"> <td runat="server" style=""> <asp:DataPager ID="DataPager1" runat="server"> <Fields> <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowLastPageButton="True" /> </Fields> </asp:DataPager> </td> </tr> </table> </LayoutTemplate> <InsertItemTemplate> <tr style=""> <td> <asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="Insert" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Clear" /> </td> <td> <asp:TextBox ID="TagTextTextBox" runat="server" Text='<%# Bind("Text") %>' /> </td> </tr> </InsertItemTemplate> <SelectedItemTemplate> <tr style=""> <td> <asp:Label ID="TagText" runat="server" Text='<%# Eval("Text") %>' /> </td> </tr> </SelectedItemTemplate> <EmptyDataTemplate> <table runat="server" style=""> <tr> <td> No data was returned. </td> </tr> </table> </EmptyDataTemplate> <EditItemTemplate> <tr style=""> <td> <asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="Update" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Cancel" /> </td> <td> <asp:TextBox ID="TagTextTextBox" runat="server" Text='<%# Bind("Text") %>' /> </td> </tr> </EditItemTemplate> <ItemTemplate> <tr style=""> <td> <asp:Label ID="TagText" runat="server" Text='<%# Eval("Text") %>' /> </td> <td> <asp:LinkButton ID="EditButton" runat="Server" Text="Edit" CommandName="Edit" /> <asp:LinkButton ID="DeleteButton" runat="Server" Text="Delete" CommandName="Delete" /> </td> </tr> </ItemTemplate> </asp:ListView> <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetTags" TypeName="LabDataContext"> </asp:ObjectDataSource> </form> </body> </html>
MyPage.ASPX.VB
Imports System Imports System.ComponentModel
Partial Class ListViewDesign Inherits System.Web.UI.Page
' GetTags <DataObjectMethodAttribute(DataObjectMethodType.Select, True)> _ Public Shared Function GetTags() As ICollection
' Create database Dim database As New LabDataContext
' Select tags Dim tags = From t In database.Tags _ Select t.TagID, _ t.Text, _ Active = t.ArticlesTags.Any
' Return tags Return tags
End Function ' GetTags
End Class
Jon Skeet [C# MVP] - 22 Feb 2008 16:40 GMT > The moment I put it outside the DataContext I get the error: > ObjectDataSource 'ObjectDataSource1' could not find a non-generic > method 'GetTags' that has no parameters. But did you update ObjectDataSource1 to point at the new type (or wherever you put it) at the same time? If not, it's no wonder that it couldn't find the method.
> This is what is driving me crazy. I really don't see any reason why > this does not work. What *exactly* did you do when you "put it outside the DataContext"?
> Yes I need paging and that was why I am return the tags as a > Collection. Then that part is fine.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet World class .NET training in the UK: http://iterativetraining.co.uk
shapper - 22 Feb 2008 18:45 GMT > > The moment I put it outside the DataContext I get the error: > > ObjectDataSource 'ObjectDataSource1' could not find a non-generic [quoted text clipped - 17 lines] > Jon Skeet - <sk...@pobox.com>http://www.pobox.com/~skeet Blog:http://www.msmvps.com/jon.skeet > World class .NET training in the UK:http://iterativetraining.co.uk Hi,
So LabDataContext is a Linq To SQL classes that contains 3 tables: Tags, Articles and ArticlesTags.
Tags > TagId, Text Articles > ArticleId, Body ArticlesTags > TagId, ArticleId
I want to feed the ListView with a Collection that has 3 columns: TagId, Text and IsActive
So I have 3 options:
1. Use only LabDataContext TypeName = "LabDataContext" Place GetTags, DeleteTag, inside the LabDataContext class
2. Create 1 extra class, for example, TagsLayer TypeName = "TagsLayer" Place GetTags, DeleteTag, inside the TagsLayer class.
3. Create 2 extra classes, for example, TagsLayer and TagsComponent TypeName = "TagsLayer" Place GetTags, DeleteTag, inside the TagsLayer class. TagsComponent would be a class with 3 properties: TagId, Text and Active
Is this the idea? What option should I use? I think my code problem was a miss understanding of how ObjectDataSource work.
Thanks, Miguel
Jon Skeet [C# MVP] - 22 Feb 2008 18:53 GMT <snip>
> Is this the idea? > What option should I use? > I think my code problem was a miss understanding of how > ObjectDataSource work. Well, I don't really see the point of object 3 - but option 2 would be okay. Then again, why not just use a LINQ to SQL data source in the first place? What additional functionality do you require?
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet World class .NET training in the UK: http://iterativetraining.co.uk
shapper - 22 Feb 2008 19:43 GMT > <snip> > [quoted text clipped - 10 lines] > Jon Skeet - <sk...@pobox.com>http://www.pobox.com/~skeet Blog:http://www.msmvps.com/jon.skeet > World class .NET training in the UK:http://iterativetraining.co.uk I was trying LinqToSQL Data source for 2 weeks. But I found a few problems ... For example, if you use a custom shape selecting you will not be able to Edit or Delete records. Am I wrong?
"One feature that will not work with custom shapes/projections, though, is inline editing support. This is because we are doing a custom projection in our Selecting event, and so the LinqDataSource has no way to safely know how to update an underlying entity object. If we want to add editing support to the GridView with a custom shaped type, we'd want to either move to using an ObjectDataSource control (where we could supply a custom Update method method to handle the updates), or have the user navigate to a new page when performing updates - and display a DetailsView or FormView control that was bound to a Product entity for editing (and not try and do inline editing with the grid)."
I read it here: http://weblogs.asp.net/scottgu/archive/2007/09/07/linq-to-sql-part-9-using-a-cus tom-linq-expression-with-the-lt-asp-linqdatasource-gt-control.aspx
So because I have the Active field I will not be able to edit the other fields.
One problem I know I will have is when I edit an Article I will want to edit its tags. So on Edit mode I will display 3 fields: ArticleTitle, ArticleBody and ArticleTags.
ArticleTags will be a list of words separated by commas. On updating I will split the string and add a record for each one in ArticlesTags.
This is my problem. I am not sure if using a simple LinqDataSource will be enough.
My other option would be creating all code in ListView events but I think using an ObjectDataSource would be better.
What do you think?
Thanks, Miguel
Jon Skeet [C# MVP] - 22 Feb 2008 22:16 GMT > I was trying LinqToSQL Data source for 2 weeks. But I found a few > problems ... > For example, if you use a custom shape selecting you will not be able > to Edit or Delete records. Am I wrong? Wouldn't like to say, to be honest - I'm not an ASP.NET expert. That's why I suggested asking in an ASP.NET group :)
> "One feature that will not work with custom shapes/projections, > though, is inline editing support. This is because we are doing a [quoted text clipped - 15 lines] > So because I have the Active field I will not be able to edit the > other fields. Fair enough.
Personally I don't tend to like using some of the built-in stuff with ASP.NET anyway - feels too much like magic which screws up as soon as you try to do anything just a *teeny* bit out of the norm. I guess you're finding that out too :)
> One problem I know I will have is when I edit an Article I will want > to edit its tags. [quoted text clipped - 7 lines] > This is my problem. I am not sure if using a simple LinqDataSource > will be enough. Sounds like it might not be.
> My other option would be creating all code in ListView events but I > think using an ObjectDataSource would be better. > > What do you think? An ObjectDataSource certainly sounds like a good compromise - and using LINQ to SQL internally, it's not like it's going to be hard to write.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet World class .NET training in the UK: http://iterativetraining.co.uk
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|