LLBLGenProDataSource2 and FormView

Posts   
 
    
DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 24-May-2007 15:22:09   

I'm getting an error when i want to update or delete an entity in a formview with the LLBLGenProDatasource2.

This is the error: "There are no primary key fields specified in the bound control and/or the bound control didn't specify any primary key fields. Delete can't continue."

It seems the formview.DataKey.Value is null at the moment i want to perform the update / delete.

I'm working with the latest version of LLBLGen.

Here's some code:


<llblgenpro:LLBLGenProDataSource2 ID="ds" runat="server" MaxNumberOfItemsToReturn="1" DataContainerType="EntityCollection" 
        AdapterTypeName="Data.DatabaseSpecific.DataAccessAdapter, DataDBSpecific"
        EntityFactoryTypeName="Data.FactoryClasses.RoleEntityFactory, Data"
        LivePersistence="False" OnPerformSelect="ds_PerformSelect" OnPerformWork="ds_PerformWork">
    </llblgenpro:LLBLGenProDataSource2>
    
 <asp:FormView ID="fvRole" DataKeyNames="RoleId" runat="server" DataSourceID="ds" CellPadding="0" Width="100%">
                                    <InsertItemTemplate>
                                        ...
                                    </InsertItemTemplate>
                                    <EditItemTemplate>
                                        <table style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px;
                                            width: 100%; border-top-style: none; padding-top: 0px; border-right-style: none;
                                            border-left-style: none; border-bottom-style: none" cellspacing="0" cellpadding="2">
                                            <tr>
                                                <td style="width: 140px">
                                                    <tdit:tdASPxLabel runat="server" Text="Nummer" ID="lblRoleNumber" TranslationProperty="Text"
                                                        TabIndex="0" TranslationTag="fieldRoleNumber:">
                                                    </tdit:tdASPxLabel>
                                                </td>
                                                <td>
                                                    <tdit:tdTextBox runat="server" Height="16px" CssClass="input" Width="100%" ID="txtRoleNumber"
                                                        TabIndex="0" RightsProperty="CheckForUpdate" Text='<%# Bind("RoleNumber") %>'>
                                                    </tdit:tdTextBox>
                                                </td>
                                            </tr>
                                            <tr>
                                                <td style="width: 140px">
                                                    <tdit:tdASPxLabel runat="server" Text="Naam" ID="lblRoleName" TranslationProperty="Text"
                                                        TabIndex="0" TranslationTag="fieldRoleName:">
                                                    </tdit:tdASPxLabel>
                                                </td>
                                                <td>
                                                    <tdit:tdTextBox runat="server" Height="16px" CssClass="input" Width="100%" ID="txtRoleName"
                                                        TabIndex="0" RightsProperty="CheckForUpdate" Text='<%# Bind("RoleName") %>'>
                                                    </tdit:tdTextBox>
                                                </td>
                                            </tr>
                                            <tr>
                                                <td style="width: 140px">
                                                    <tdit:tdASPxLabel runat="server" Text="Verkorte naam" ID="lblRoleNameShort" TranslationProperty="Text"
                                                        TabIndex="0" TranslationTag="fieldRoleNameShort:">
                                                    </tdit:tdASPxLabel>
                                                </td>
                                                <td>
                                                    <tdit:tdTextBox runat="server" Height="16px" CssClass="input" Width="100%" ID="txtRoleNameShort"
                                                        TabIndex="0" RightsProperty="CheckForUpdate" Text='<%# Bind("RoleNameShort") %>'>
                                                    </tdit:tdTextBox>
                                                </td>
                                            </tr>
                                            <tr>
                                                <td style="width: 140px">
                                                    &nbsp;
                                                </td>
                                                <td>
                                                    <asp:Label runat="server" ID="txtRoleId" Text='<%# Bind("RoleId") %>'></asp:Label>
                                                </td>
                                            </tr>
                                        </table>
                                    </EditItemTemplate>
                                </asp:FormView>

And this is my code behind:


protected void ds_PerformSelect(object sender, PerformSelectEventArgs2 e)
        {
            try
            {
                using (DataAccessAdapter adapter = new DataAccessAdapter())
                {
                    adapter.FetchEntityCollection(e.ContainedCollection, e.Filter, e.MaxNumberOfItemsToReturn, e.Sorter, e.PrefetchPath, e.PageNumber, e.PageSize);
                }
            }
            catch (Exception ex)
            {
                Globals.logger.LogError(ex);
            }
        }

        protected void ds_PerformWork(object sender, PerformWorkEventArgs2 e)
        {
            try
            {
                List<UnitOfWorkElement2> elementsToInsert = e.Uow.GetEntityElementsToInsert();
                if (elementsToInsert.Count > 0)
                {
                    ((RoleEntity)elementsToInsert[0].Entity).CompanyId = Globals.config.CompanyId;
                }

                using (DataAccessAdapter adapter = new DataAccessAdapter())
                {
                    e.Uow.Commit(adapter, true);
                }
            }
            catch (Exception ex)
            {
                Globals.logger.LogError(ex);
            }
        }

protected override void BaseEntityPage_ToolBarDeleteClicked()
        {
            base.BaseEntityPage_ToolBarDeleteClicked();

            try
            {
                if (!this.NewEntity)
                {
                    fvRole.DeleteItem();
                }
                
                Response.Redirect("RightsAndRoles.aspx");
            }
            catch (Exception ex)
            {
                Globals.logger.LogError(ex);
            }
        }

Same for update, but with fvRole.UpdateItem(bool);

I hope someone can help me with this problem.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 24-May-2007 15:37:15   
  • Make sure you have the latest runtime libraries available. (this error might appear in old versions)
  • No PK fields found error is often caused by case mismatches between the PK field name of the entity and the name specified in the grid HTML. Could you check that for me please? (For example, name of PK field is 'OrderId' and the name specified in the formView is OrderID. This doesn't match)
DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 24-May-2007 16:03:54   

I've double checked the name of the PK field and the name specfied in the formview. In both ways it is "RoleId".

I'm also working with the same runtime libraries as used in the AdditionalTemplate_DbEditor. When i run that project, everything works fine.

When i compare the code of my project with the code of the AdditionalTemplate_DbEditor GUI project, i can't find any big differences.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 25-May-2007 10:34:05   

_The runtime library version is obtainable by rightclicking the SD.LLBLGen.Pro.ORMSupportClasses.NETxy.dll in windows explorer and then by selecting properties and the version tab. The version is then enlisted at the top as the fileversion. It has the typical format as 2.0.0.YYMMDD, or starting in 2007, the format 2.0.YY.MMDD _

Please make sure you download and use the latest available version. Thanks

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 25-May-2007 11:30:18   

SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll version 2.0.7.402 I think that's new enough.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 25-May-2007 11:54:31   

Does this occur also when you click on a 'delete' or 'update' button on the grid itself? Also, why do you have a Response.Redirect() in the delete routine? that shouldn't be necessary simply because the page already posted back and should re-render.

Frans Bouma | Lead developer LLBLGen Pro
DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 25-May-2007 13:40:53   

It's a formview, not a grid. When i add a button with a commandargument to the formview, this also happen with a update or delete.

I'm doing a Respone.Redirect, because this the user has to be redirected to another page, it's not because of a page refresh or something.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 25-May-2007 16:09:35   

Just for the sake of trial, would you please modify this line:

<td>
                                                    <asp:Label runat="server" ID="txtRoleId" Text='<%# Bind("RoleId") %>'></asp:Label>
                                                </td>

into:

<td>
                                                    <asp:Label runat="server" ID="txtRoleId" Text='<%# Eval("RoleId") %>'></asp:Label>
                                                </td>

If this doesn't work, would you please handle the ItemDeleted, ItemInserted and ItemUpdated events of the ForView and see if these get called.

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 25-May-2007 16:33:20   

Doesn't change a thing. Same error.

But when i look into the AdditionalTemplate_DbEditor GUI project, i see this:


<tr>
            <td width="20"  nowrap="nowrap" class="content">&nbsp;</td>
            <td class="formtexts" >
                RoleId:
            </td>
            <td class="content">
                <asp:Label ID="lblRoleId" runat="server" Text='<%# Bind("RoleId") %>'/>         </td>
            <td width="20" nowrap="nowrap" class="content">&nbsp;</td>
        </tr>

And there it works fine.

EDIT: I've checked the ItemUpdating and ItemUpdated events. They both get triggered. But in the ItemUpdating event no key is found. The ItemUpdated event gives the exception from above.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 25-May-2007 19:55:52   

I still think its the response.redirect. I fail to see why you need that: you click a button, the page posts back, you process the click event, that's it. the page should render. You don't have to redirect to the same page.

Frans Bouma | Lead developer LLBLGen Pro
DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 29-May-2007 09:48:49   

But the redirect is not to the same page. it's to another page.

Without the Response.Redirect it won't work either. Same error.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 29-May-2007 11:30:58   

I can't reproduce it.

html:


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default16.aspx.cs" Inherits="Default16" %>
<%@ Register Assembly="SD.LLBLGen.Pro.ORMSupportClasses" Namespace="SD.LLBLGen.Pro.ORMSupportClasses" TagPrefix="cc1" %>

<!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>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <cc1:LLBLGenProDataSource2 ID="_ordersDS" runat="server" AdapterTypeName="NWTest.DatabaseSpecific.DataAccessAdapter, NWTestDBSpecific" DataContainerType="EntityCollection" EntityFactoryTypeName="NWTest.FactoryClasses.OrdersEntityFactory, NWTest" LivePersistence="False" OnPerformSelect="_ordersDS_PerformSelect" OnPerformWork="_ordersDS_PerformWork">
        </cc1:LLBLGenProDataSource2>

            <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Delete selected" /><br />
        Orders<asp:FormView ID="_form" runat="server" DataKeyNames="OrderId" DataSourceID="_ordersDS">
            <ItemTemplate>
                OrderId:
                <asp:Label ID="OrderIdLabel" runat="server" Text='<%# Eval("OrderId") %>'></asp:Label><br />
                CustomerId:
                <asp:Label ID="CustomerIdLabel" runat="server" Text='<%# Bind("CustomerId") %>'></asp:Label><br />
                EmployeeId:
                <asp:Label ID="EmployeeIdLabel" runat="server" Text='<%# Bind("EmployeeId") %>'></asp:Label><br />
                OrderDate:
                <asp:Label ID="OrderDateLabel" runat="server" Text='<%# Bind("OrderDate") %>'></asp:Label><br />
                RequiredDate:
                <asp:Label ID="RequiredDateLabel" runat="server" Text='<%# Bind("RequiredDate") %>'></asp:Label><br />
                ShippedDate:
                <asp:Label ID="ShippedDateLabel" runat="server" Text='<%# Bind("ShippedDate") %>'></asp:Label><br />
                ShipVia:
                <asp:Label ID="ShipViaLabel" runat="server" Text='<%# Bind("ShipVia") %>'></asp:Label><br />
                Freight:
                <asp:Label ID="FreightLabel" runat="server" Text='<%# Bind("Freight") %>'></asp:Label><br />
                ShipName:
                <asp:Label ID="ShipNameLabel" runat="server" Text='<%# Bind("ShipName") %>'></asp:Label><br />
                ShipAddress:
                <asp:Label ID="ShipAddressLabel" runat="server" Text='<%# Bind("ShipAddress") %>'></asp:Label><br />
                ShipCity:
                <asp:Label ID="ShipCityLabel" runat="server" Text='<%# Bind("ShipCity") %>'></asp:Label><br />
                ShipRegion:
                <asp:Label ID="ShipRegionLabel" runat="server" Text='<%# Bind("ShipRegion") %>'></asp:Label><br />
                ShipPostalCode:
                <asp:Label ID="ShipPostalCodeLabel" runat="server" Text='<%# Bind("ShipPostalCode") %>'></asp:Label><br />
                ShipCountry:
                <asp:Label ID="ShipCountryLabel" runat="server" Text='<%# Bind("ShipCountry") %>'></asp:Label><br />
                <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit">
                </asp:LinkButton>
                <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete">
                </asp:LinkButton>
                <asp:LinkButton ID="NewButton" runat="server" CausesValidation="False" CommandName="New" Text="New">
                </asp:LinkButton>
            </ItemTemplate>
        </asp:FormView>
    </div>
    </form>
</body>
</html>

codebehind:


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using SD.LLBLGen.Pro.ORMSupportClasses;
using NWTest.HelperClasses;
using NWTest.DatabaseSpecific;

public partial class Default16 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if(!Page.IsPostBack)
        {
            _ordersDS.FilterToUse = new RelationPredicateBucket(OrdersFields.CustomerId == "ALFKI");
            _ordersDS.SorterToUse = new SortExpression(OrdersFields.OrderId | SortOperator.Descending);
        }
    }

    protected void _ordersDS_PerformSelect(object sender, SD.LLBLGen.Pro.ORMSupportClasses.PerformSelectEventArgs2 e)
    {
        using(DataAccessAdapter adapter = new DataAccessAdapter())
        {
            adapter.FetchEntityCollection(e.ContainedCollection, e.Filter, e.MaxNumberOfItemsToReturn, e.Sorter, null);
        }
    }

    protected void _ordersDS_PerformWork(object sender, SD.LLBLGen.Pro.ORMSupportClasses.PerformWorkEventArgs2 e)
    {
        using(DataAccessAdapter adapter = new DataAccessAdapter())
        {
            e.Uow.Commit(adapter, true);
        }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        _form.DeleteItem();
    }
}

Now, I don't use a toolbar as you do (I couldn't find it in the standard controls, I'm sure I'm overlooking it), so I used a button. It simply removes the selected order from the db.

Frans Bouma | Lead developer LLBLGen Pro
DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 29-May-2007 12:27:34   

Well, i've also reproduced the problem on a simple webform and everything seems to work fine.

The problem is a tabcontrol (from DevExpress) i'm using in my normal project. Without this tabcontrol, the update/delete work fine.

So, my question was asked on the wrong forum. Sorry for that and thanks for the help.

jbb avatar
jbb
User
Posts: 267
Joined: 29-Nov-2005
# Posted on: 29-May-2007 15:53:40   

Hello,

Maybe your custom tabcontrol clear/modify the viewstate of all the child controls. Did you have any params that can modify the viewstate management?

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 29-May-2007 16:22:00   

Well, i had some problems earlier with this control. So i threw the control away out of the project.

I'm now using the tabcontainer from the AJAX framework. This control works really good.

jbb avatar
jbb
User
Posts: 267
Joined: 29-Nov-2005
# Posted on: 29-May-2007 16:26:38   

Ok, thanks for the feedback.

SanderF
User
Posts: 125
Joined: 11-Dec-2006
# Posted on: 28-Aug-2007 11:28:09   

DvK wrote:

Well, i had some problems earlier with this control. So i threw the control away out of the project.

I'm now using the tabcontainer from the AJAX framework. This control works really good.

Hi DvK,

We used the DevEpxress tabControl as well and had the same issue. However, switching to ajaxcontroltoolkit didn't do the trick. Can you maybe give me a hint of how you solved it??

Thanks in advance

Sorry to misuse this forum