Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / February 2008

Tip: Looking for answers? Try searching our database.

ObjectDataSource and Linq. Please, help! I don't know what else to     try. Thank You.

Thread view: 
Enable EMail Alerts  Start New Thread
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 Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.