yasser777 / nettiers

Automatically exported from code.google.com/p/nettiers
0 stars 0 forks source link

EntityGridView + DataSource with QueryStringParameter raises exception on delete #364

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Add a EntityGridView and bind it to a data source with a 
QueryStringParameter Add Delete button.
2. Open URL Menuedit.aspx?MenuId=1 (see below) 
3. Click delete button and it raises exception

What is the expected output? What do you see instead?
Expect to see no exception and the record deleted

What version of .netTiers and CodeSmith are you using?
netTiers v2.3.1.870

Please provide any additional information below.

<b>Example Menuedit.aspx:</b>

    <data:EntityGridView runat="server" ID="grid" DataSourceID="MenuDS" DataKeyNames="MenuId">
        <Columns>
            <asp:HyperLinkField DataNavigateUrlFormatString="MenuEditor.aspx?MenuId={0}"
                 DataNavigateUrlFields="MenuId" HeaderText="Name" SortExpression="[Name]" 
                 DataTextField="Name" />
            <asp:CommandField ShowDeleteButton="true" />
        </Columns>
    </data:EntityGridView>
    <data:MenuDataSource runat="server" ID="MenuDS" SelectMethod="GetByOwner" 
          EnableDeepLoad="true" EnableSorting="true" EnablePaging="true"
          EnableTransaction="false">
        <DeepLoadProperties>
            <Types>
                <data:MenuProperty Name="Menu" />
            </Types>
        </DeepLoadProperties>
        <Parameters>
            <asp:QueryStringParameter Name="Owner" 
                 ConvertEmptyStringToNull="true" QueryStringField="MenuId" />
        </Parameters>
    </data:MenuDataSource>

<b>Example Database structure</b>

CREATE TABLE [dbo].[Menu](
    [MenuId] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](256) NOT NULL,
    [Owner] [int] NULL,
 CONSTRAINT [PK_Menu] PRIMARY KEY CLUSTERED 
(
    [MenuId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Menu]  WITH CHECK ADD  CONSTRAINT [FK_Menu_Menu] FOREIGN 
KEY([Owner])
REFERENCES [dbo].[Menu] ([MenuId])
GO
ALTER TABLE [dbo].[Menu] CHECK CONSTRAINT [FK_Menu_Menu]

<b>Example Data</b>

Set Identity_Insert [dbo].[Menu] ON
INSERT INTO [[dbo].[Menu] ([Name] ,[Owner]) VALUES ('item1' ,NULL)
INSERT INTO [[dbo].[Menu] ([Name] ,[Owner]) VALUES ('item2' ,NULL)
INSERT INTO [[dbo].[Menu] ([Name] ,[Owner]) VALUES ('item3' ,NULL)
INSERT INTO [[dbo].[Menu] ([Name] ,[Owner]) VALUES ('item5' ,1)
INSERT INTO [[dbo].[Menu] ([Name] ,[Owner]) VALUES ('item6' ,1)
INSERT INTO [[dbo].[Menu] ([Name] ,[Owner]) VALUES ('item7' ,2)
Set Identity_Insert [dbo].[Menu] OFF

-------------------
Notes
-------------------

As for as I can see, Here is the point of error in

MyApp.Web.Data.BaseDataSourceView.ExecuteDelete(IDictionary keys, IDictionary 
oldValues)

If I replace   
  IList<Entity> entityList = GetEntityList(keys); //this gets entities that are as as if 
                                                  //the QueryStringParameter was absent
with
  IList<Entity> entityList = GetEntityList(GetParameterValues()); //then it works.. 

Original issue reported on code.google.com by vaibhavk...@gmail.com on 17 Jan 2011 at 9:40

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Corrected Example Data

Set Identity_Insert [dbo].[Menu] ON
INSERT INTO [[dbo].[Menu] (MenuId, [Name] ,[Owner]) VALUES (1,'item1' ,NULL)
INSERT INTO [[dbo].[Menu] (MenuId, [Name] ,[Owner]) VALUES (2,'item2' ,NULL)
INSERT INTO [[dbo].[Menu] (MenuId, [Name] ,[Owner]) VALUES (3,'item3' ,NULL)
INSERT INTO [[dbo].[Menu] (MenuId, [Name] ,[Owner]) VALUES (4,'item5' ,1)
INSERT INTO [[dbo].[Menu] (MenuId, [Name] ,[Owner]) VALUES (5,'item6' ,1)
INSERT INTO [[dbo].[Menu] (MenuId, [Name] ,[Owner]) VALUES (6,'item7' ,2)
Set Identity_Insert [dbo].[Menu] OFF

Original comment by vaibhavk...@gmail.com on 17 Jan 2011 at 10:53

GoogleCodeExporter commented 9 years ago

Original comment by bniemyjski on 18 Jan 2011 at 6:41

GoogleCodeExporter commented 9 years ago
An update, I have the same issue when using a EntitydataSource with ListView:

<asp:ListView runat="server" ID="options" DataSourceID="ods" 
DataKeyNames="ManagedContentId"
        ItemPlaceholderID="itemph">
        <LayoutTemplate>
            <table cellpadding="5" cellspacing="0">
                <asp:PlaceHolder runat="server" ID="itemph" />
            </table>
        </LayoutTemplate>
        <ItemTemplate>
            <tr>
                <td colspan="2">
                    <%# Eval("Title") %>
                </td>
                <td>
                </td>
            </tr>
            <tr>
                <td style="background-color: #e0e0e0;">
                    <%# Eval("PageTitle") %>
                </td>
                <td style="background-color: #efefef;">

                        <%# Eval("Text") %>
                </td>
                <td>
                    <asp:LinkButton runat="server" CommandName="Edit" Text="Edit" CausesValidation="false" />
                </td>
            </tr>
        </ItemTemplate>
        <EditItemTemplate>
            <tr>
                <td colspan="2">
                    <%# Eval("Title") %>
                </td>
                <td>
                </td>
            </tr>
            <tr>
                <td style="background-color: #e0e0e0;">
                    <%# Eval("PageTitle") %>
                </td>
                <td style="background-color: #efefef;">
                    <asp:TextBox runat="server" ID="tbValue" Text='<%# Bind("Text") %>' />
                </td>
                <td>
                    <asp:LinkButton runat="server" CommandName="Update" Text="Save" CausesValidation="false" />
                    <asp:LinkButton runat="server" CommandName="Cancel" Text="Cancel" CausesValidation="false" />
                </td>
            </tr>
        </EditItemTemplate>
    </asp:ListView>

    <data:ManagedContentDataSource runat="server" ID="ods" SelectMethod="GetByContentTypeId" EnableTransaction="false">
        <Parameters>
            <asp:Parameter Name="ContentTypeId" DefaultValue="11" />
        </Parameters>
    </data:ManagedContentDataSource>

=============================================================
/****** Object:  Table [dbo].[ContentType]    Script Date: 08/23/2011 14:37:13 
******/
CREATE TABLE [dbo].[ContentType](
    [ContentTypeId] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](256) NOT NULL,
    [Usage] [nvarchar](1024) NOT NULL,
 CONSTRAINT [PK_ContentType] PRIMARY KEY CLUSTERED 
(
    [ContentTypeId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

/****** Object:  Table [dbo].[ManagedContent]    Script Date: 08/23/2011 
14:35:52 ******/
CREATE TABLE [dbo].[ManagedContent](
    [ManagedContentId] [int] IDENTITY(1,1) NOT NULL,
    [ContentTypeId] [int] NOT NULL,
    [Name] [nvarchar](256) NOT NULL,
    [Title] [nvarchar](1024) NOT NULL,
    [Text] [nvarchar](max) NOT NULL,
    [PageTitle] [nvarchar](1024) NOT NULL,
 CONSTRAINT [PK_ManagedContent] PRIMARY KEY CLUSTERED 
(
    [ManagedContentId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[ManagedContent]  WITH CHECK ADD  CONSTRAINT 
[FK_ManagedContent_ContentType] FOREIGN KEY([ContentTypeId])
REFERENCES [dbo].[ContentType] ([ContentTypeId])
GO

ALTER TABLE [dbo].[ManagedContent] CHECK CONSTRAINT 
[FK_ManagedContent_ContentType]
GO
=====================================================

The error happens in: MyApp.Web/Data/BaseDataSource.cs:

MyApp.Web.Data.BaseDataSource.ExecuteUpdate(IDictionary keys, IDictionary 
values, IDictionary oldValues)

If I replace   
  IList<Entity> entityList = GetEntityList(keys); //this gets entities that are as as if 
                                                  //the QueryStringParameter was absent
with
  IList<Entity> entityList = GetEntityList(GetParameterValues()); //then it works.. 

// 'keys' are the DataKeyNames values of the ListView/Gridview where as 
EntityList must be fetched from the parameters of the data source.

=======================================================

>>>> PLEASE READ <<<<<
I am looking for confirmation that this is a good change. Please update?

I am not familiar what might break if I do this.

Please reply this time :)

It was vary hard to troubleshoot and reach the same bug twice :(

Original comment by vaibhavk...@gmail.com on 23 Aug 2011 at 9:16

GoogleCodeExporter commented 9 years ago

Correction: it is BaseDataSourceView and not BaseDataSource

The error happens in: MyApp.Web/Data/BaseDataSource.cs:

MyApp.Web.Data.BaseDataSourceView.ExecuteUpdate(IDictionary keys, IDictionary 
values, IDictionary oldValues)

------------------------
More info:

>The bug/exception happens when u click edit and then update for the listview 
item.

>If I change DataSource to use SQL parameters then it does not cause an 
exception
ie:
    <data:ManagedContentDataSource runat="server" ID="ods" SelectMethod="GetPaged" EnableTransaction="false">
        <Parameters>
            <data:SqlParameter Name="WhereClause" UseParameterizedFilters="false">
                <Filters>
                    <data:ManagedContentFilter Column="ContentTypeId" ComparisionType="Equals" DefaultValue="11" />
                </Filters>
            </data:SqlParameter></Parameters>
    </data:ManagedContentDataSource>

Original comment by vaibhavk...@gmail.com on 23 Aug 2011 at 9:40

GoogleCodeExporter commented 9 years ago
Thanks for all of this extra information (it's appreciated), I'll take a look 
and let you know what I find.

Thanks
-Blake

Original comment by bniemyjski on 23 Aug 2011 at 8:59

GoogleCodeExporter commented 9 years ago
Hello,

There should be nothing wrong with changing that from GetEntityList(keys) to 
GetEntityList(GetParameterValues()). If you set a breakpoint on this in the 
BaseDataSourceView, is keys even set to anything?. From what I can tell its 
only ever passed a new HashTable or Null.

I followed the Call to GetEntityList and if the entity list is set to null 
(line 1336) it will call GetSelectData in your derived data source (E.G., 
ManagedContentDataSource) by passing in those values. If those values  (e.g. 
keys) are null or is empty then it will call GetParameterValues().

protected override IList<Category> GetSelectData(IDictionary values, out int 
count)
        {
            if (values == null || values.Count == 0) values = CollectionsUtil.CreateCaseInsensitiveHashtable(GetParameterValues());

So the questions are, does keys have an initial value? and if not, is it making 
this call to initialize the keys collection in the overridden GetSelectData? If 
so, is the call to GetParameterValues() calling or getting the same value that 
your setting in the base implementation?

Original comment by bniemyjski on 1 Sep 2011 at 8:01

GoogleCodeExporter commented 9 years ago
in your new base implementation*

Original comment by bniemyjski on 1 Sep 2011 at 8:02