GridView edit exception

Posts   
 
    
JohnL
User
Posts: 47
Joined: 07-Oct-2005
# Posted on: 21-Dec-2006 23:42:42   

LLBLGen Pro Version: 2.0.0. Final (December 6th, 2006)

ORMSupportClasses.NET20.dll version 2.0.0.61205 DQE.SqlServer.NET20.dll version 2.0.0.61120 (These match between the project's /bin folder and the LLBLGen installation)

The exception:

Server Error in '/TestProject' Application. There are no primary key fields specified in the bound control and/or the bound control didn't specify any primary key fields. Update can't continue. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: SD.LLBLGen.Pro.ORMSupportClasses.ORMGeneralOperationException: There are no primary key fields specified in the bound control and/or the bound control didn't specify any primary key fields. Update can't continue.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[ORMGeneralOperationException: There are no primary key fields specified in the bound control and/or the bound control didn't specify any primary key fields. Update can't continue.] SD.LLBLGen.Pro.ORMSupportClasses.LLBLGenProDataSourceView2.ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues) +512 System.Web.UI.DataSourceView.Update(IDictionary keys, IDictionary values, IDictionary oldValues, DataSourceViewOperationCallback callback) +78 System.Web.UI.WebControls.GridView.HandleUpdate(GridViewRow row, Int32 rowIndex, Boolean causesValidation) +1215 System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup) +858 System.Web.UI.WebControls.GridView.OnBubbleEvent(Object source, EventArgs e) +95 System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35 System.Web.UI.WebControls.GridViewRow.OnBubbleEvent(Object source, EventArgs e) +117 System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35 System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +115 System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +163 System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7 System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11 System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +174 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5102

Version Information: Microsoft .NET Framework Version:2.0.50727.42; ASP.NET Version:2.0.50727.210 Using template group C#, .NET 2.0, Adapter.

The database is SQL Server 2000.

The aspx file:

<%@ Reference Page="~/webtemplates/menupage.aspx" %>
<%@ Page Language="C#" Inherits="Financing_FinanceRates" 
    MasterPageFile="~/MasterPages/TestProject.master" CodeFile="FinanceRates.aspx.cs" 
    CodeFileBaseClass="TestProject.MenuForm"%>

<%@ Register Assembly="SD.LLBLGen.Pro.ORMSupportClasses.NET20" Namespace="SD.LLBLGen.Pro.ORMSupportClasses"
    TagPrefix="llblgenpro" %>
<%@ MasterType VirtualPath="~/MasterPages/TestProject.master" %>

<asp:Content ID="PageContent" ContentPlaceHolderID="MasterMainContent" Runat="Server">
    <table border="0" cellpadding="0" cellspacing="0" width="55%" align="center">
        <tr>
            <td align="center" style="text-align:center; width: 100%;">
                <asp:GridView Width="100%" ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="PremiumFinanceId"
                    DataSourceID="LLBLGenProDataSource2_1" AutoGenerateEditButton="True">
                    <Columns>
                        <asp:BoundField DataField="PremiumFinanceId" HeaderText="PremiumFinanceId" ReadOnly="True"
                            SortExpression="PremiumFinanceId" Visible="False" />
                        <asp:BoundField DataField="FinanceOrgId" HeaderText="FinanceOrgId" SortExpression="FinanceOrgId"
                            Visible="False" />
                        <asp:BoundField DataField="EffectiveDate" HeaderText="Effective Date" SortExpression="EffectiveDate" />
                    </Columns>
                </asp:GridView>
                <asp:Button ID="addNewFinance" runat="server" Text="Add New Finance Data" />
            </td>
        </tr>
    </table>
    <llblgenpro:llblgenprodatasource2 id="LLBLGenProDataSource2_1" runat="server" 
        adaptertypename="ImkOrm.DatabaseSpecific.DataAccessAdapter, ImkOrmDBSpecific"
        datacontainertype="EntityCollection" entityfactorytypename="ImkOrm.FactoryClasses.PremiumFinanceEntityFactory, ImkOrm">
    </llblgenpro:llblgenprodatasource2>
</asp:Content>


The corresponding aspx.cs:

using System;
using System.Web.UI.WebControls;
using ImkOrm.HelperClasses;
using TestProject;

public partial class Financing_FinanceRates : MenuForm
{
    new protected void Page_Load(object sender, EventArgs e)
    {
        Master.IsMainMenuLink = true;
        Master.IsShowLogOff = true;
        Master.PageTitle = "Financing Rates";
        // Setup the basic objects
        Master.SetupObject();

        addNewFinance.PostBackUrl = "/TestProject/Financing/FinanceRatesEdit.aspx?" + Master.applicationManagerObject.FrameParameter;

        GridView1.Sort(PremiumFinanceFields.EffectiveDate.Name.ToString(), 
            SortDirection.Descending);

        Master.SetupTopBottom();
    }
}

There are no inheritance hierarchies in use nor any custom made templates.

The problem here is that clicking the Edit button and then the update button throws this exception.

The aspx tag...

<asp:GridView Width="100%" ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="PremiumFinanceId"
    DataSourceID="LLBLGenProDataSource2_1" AutoGenerateEditButton="True">

Lists

DataKeyNames="PremiumFinanceId" 

which is the primary key of the entity (I have checked the case and the entity does use the casing seen here).

Meanwhile, another very similar page:


<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/MasterPages/TestProject.master" CodeFile="FinanceRatesEdit.aspx.cs" Inherits="Financing_FinanceRatesEdit" %>

<%@ Register Assembly="SD.LLBLGen.Pro.ORMSupportClasses.NET20" Namespace="SD.LLBLGen.Pro.ORMSupportClasses"
    TagPrefix="llblgenpro" %>

<asp:Content ID="PageContent" ContentPlaceHolderID="MasterMainContent" Runat="Server">
    <table border="0" cellpadding="0" cellspacing="0" width="55%" align="center">
        <tr>
            <td align="center" style="text-align:center" width="100%">
    <asp:DetailsView  Width="100%" ID="DetailsView1" runat="server" AutoGenerateRows="False" DataKeyNames="PremiumFinanceId"
        DataSourceID="LLBLGenProDataSource2_1" Height="50px" DefaultMode="Insert" OnItemInserting="DetailsView1_ItemInserting">
        <Fields>
            <asp:BoundField DataField="PremiumFinanceId" HeaderText="PremiumFinanceId" ReadOnly="True"
                SortExpression="PremiumFinanceId" Visible="False" />
            <asp:BoundField DataField="FinanceOrgId" HeaderText="FinanceOrgId" SortExpression="FinanceOrgId" Visible="False" />
            <asp:BoundField DataField="EffectiveDate" HeaderText="Effective Date" SortExpression="EffectiveDate" >
                <HeaderStyle CssClass="Question" />
            </asp:BoundField>
        </Fields>
    </asp:DetailsView>
    <asp:Button ID="savenew" runat="server" Text="Save New" OnClick="savenew_Click" />
    <asp:Button ID="cancel" runat="server" Text="Cancel" OnClick="cancel_Click" />
            </td>  
        </tr>
    </table>
    <llblgenpro:llblgenprodatasource2 id="LLBLGenProDataSource2_1" runat="server" adaptertypename="ImkOrm.DatabaseSpecific.DataAccessAdapter, ImkOrmDBSpecific"
        datacontainertype="EntityCollection" entityfactorytypename="ImkOrm.FactoryClasses.PremiumFinanceEntityFactory, ImkOrm"></llblgenpro:llblgenprodatasource2>
</asp:Content>
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using TestProject.GenericObjects;

public partial class Financing_FinanceRatesEdit : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Master.IsMainMenuLink = false;
        Master.IsShowLogOff = true;
        Master.PageTitle = "Financing Rate Edit";

        DetailsView1.DefaultMode = DetailsViewMode.Insert;
        // Setup the basic objects
        Master.SetupObject();

        string parentUrl = string.Format("/TestProject/Financing/FinanceRates.aspx?{0}",
            (Master.applicationManagerObject.FrameParameter)); 
        cancel.PostBackUrl = parentUrl;

        Master.TopLinks.Add(new UrlInfo(parentUrl, "Back", "BackButton"));

        Master.SetupTopBottom();
    }

    protected void cancel_Click(object sender, EventArgs e)
    {
        
    }
    protected void savenew_Click(object sender, EventArgs e)
    {
        DetailsView1.InsertItem(true);
    }
    protected void DetailsView1_ItemInserting(object sender, DetailsViewInsertEventArgs e)
    {
        e.Values["FinanceOrgId"] = 0;
    }
}

Inserts new records properly.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 22-Dec-2006 08:54:03   

What's the database type of the PK? Is it a GUID?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 22-Dec-2006 10:37:45   

Odd. The exception is thrown inside the ExecuteUpdate routine when the keys dictionary (which contains the PK field names) passed in by the control (the gridview in this case) is empty... So the data passed into the datasourcecontrol by the gridview isn't correct, but I have no idea why this is... If you enable visibility of the pk column, does that make a difference?

Frans Bouma | Lead developer LLBLGen Pro
JohnL
User
Posts: 47
Joined: 07-Oct-2005
# Posted on: 22-Dec-2006 17:04:50   

Walaa wrote:

What's the database type of the PK? Is it a GUID?

Yes it is a GUID.

JohnL
User
Posts: 47
Joined: 07-Oct-2005
# Posted on: 22-Dec-2006 17:11:43   

Otis wrote:

Odd. The exception is thrown inside the ExecuteUpdate routine when the keys dictionary (which contains the PK field names) passed in by the control (the gridview in this case) is empty... So the data passed into the datasourcecontrol by the gridview isn't correct, but I have no idea why this is... If you enable visibility of the pk column, does that make a difference?

Making the columns visible makes no difference. The data loads correctly into them, however.

JohnL
User
Posts: 47
Joined: 07-Oct-2005
# Posted on: 22-Dec-2006 17:32:35   

For reference, this is the SQL to create the table:

CREATE TABLE [PremiumFinance] (
    [PremiumFinanceID]  uniqueidentifier ROWGUIDCOL  NOT NULL CONSTRAINT [DF_PremiumFinance_PremiumFinanceID] DEFAULT (newid()),
    [FinanceOrgID] [int] NOT NULL ,
    [EffectiveDate] [datetime] NOT NULL ,
    CONSTRAINT [PK_PremiumFinance] PRIMARY KEY  NONCLUSTERED 
    (
        [PremiumFinanceID]
    )  ON [PRIMARY] 
) ON [PRIMARY]
GO

In LLBLGen 2.0 all three fields are the default mappings created simply by adding the table as an entity ("Add New Entities Mapped on Tables from Catalog(s)" and then clicking the new table).

Chester
Support Team
Posts: 223
Joined: 15-Jul-2005
# Posted on: 23-Dec-2006 23:30:10   

Hmmm. The obvious difference between the two pages in question is that the one throwing an exception uses the data source control. Can you try one thing first - try wrapping the code on your Page_Load event in an if(IsPostback) block?

JohnL
User
Posts: 47
Joined: 07-Oct-2005
# Posted on: 27-Dec-2006 17:26:13   

Further experimentation shows that the page can update successfully as long I comment out this line:

    //GridView1.Sort(PremiumFinanceFields.EffectiveDate.Name.ToString(), 
    //  SortDirection.Descending);

Apparently applying a sort to a bound GridView causes it to lose track of the primary key? I don't see this happening when bound to traditional data sets...

JohnL
User
Posts: 47
Joined: 07-Oct-2005
# Posted on: 27-Dec-2006 19:11:37   

JohnL wrote:

Walaa wrote:

What's the database type of the PK? Is it a GUID?

Yes it is a GUID.

Just to see if that makes any difference, I changed the ID to an "int IDENTITY (1, 1) NOT NULL" and it does the same thing.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 28-Dec-2006 08:11:38   
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 28-Dec-2006 11:14:22   

I have no idea why the grid doesn't pass any pk field names to the call to the routine... If I check our own test forms and real application forms using the datasource control, they too have these kind of columns, and work OK. The only thing I don't have is the gridview sort you set in the pageload...

Frans Bouma | Lead developer LLBLGen Pro
Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 28-Dec-2006 14:59:59   

A wild guess:

Maybe it would work if you move the sort to another later event in the ASP.NET page cycle. Maybe in the PreLoad or LoadComplete events