- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
PreformWork not firing for some records
Joined: 05-Jul-2006
I have a page with a detailsview and a gridview. The details view allows the user to page, insert and update (along with canceling these events). The grid view allows the user to see the data heirchary, delete entities and "select" entities. When a user selects an entity they are taken directly to the detailsview page index in edit mode.
The entity can relate to itself. if parent_tag_id is null it is a parent. If not it is a child. There can only be parents and children (no grandchildren)
CREATE TABLE [tag] (
[tag_id] [int] IDENTITY (1, 1) NOT NULL ,
[description] [varchar] (20) NOT NULL ,
[parent_tag_id] [int] NULL ,
[active] [bit] NOT NULL CONSTRAINT DEFAULT (1),
CONSTRAINT [tag__PK] PRIMARY KEY CLUSTERED ([tag_id]) ON [PRIMARY] ,
CONSTRAINT [fk_tag_tag__parent_tag_id_tag_id] FOREIGN KEY ([parent_tag_id]) REFERENCES [tag] ([tag_id])
)
create trigger tr_tag_u on tag after update
as
begin
--set children of inactive parents to parent tags
update tag set parent_tag_id = null
from tag t inner join inserted i on t.parent_tag_id = i.tag_id
where i.active = 0
--if the parent became a child, set children to parents
if exists(select 1 from inserted i inner join deleted d on i.tag_id = d.tag_id where i.parent_tag_id is not null and d.parent_tag_id is null) begin
update tag set parent_tag_id = null
from tag t
inner join inserted i on t.parent_tag_id = i.tag_id
inner join deleted d on i.tag_id = d.tag_id
where i.parent_tag_id is not null and d.parent_tag_id is null
end
end
I have everything working except for an odd occurance in the detailsview. If I insert a new record or edit a child record the performwork event for the detailsview is executed with no issues.
If I edit a parent record the performwork event does not fire. I'm at a loss as to why this might be.
ASP.Net 2.0 LLBL Gen 2.0 Adapter SQL Server 2K
aspx
<asp:DetailsView ID="dvTags" runat="server" AllowPaging="True" AutoGenerateRows="False" DataSourceID="odsTags2" DataKeyNames="TagId,ParentTagId" OnDataBound="dvTags_DataBound">
<Fields>
<asp:TemplateField HeaderText="Description">
<EditItemTemplate>
<asp:TextBox ID="txtEditTag" runat="server" Text='<%# Bind("Description") %>' />
<asp:RequiredFieldValidator ID="rfvtxtEditTag" runat="server" ErrorMessage="Tag description is required" ControlToValidate="txtEditTag" EnableViewState="false" SetFocusOnError="true">*</asp:RequiredFieldValidator>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="txtAddTag" runat="server" Text='<%# Bind("Description") %>' />
<asp:RequiredFieldValidator ID="rfvtxtAddTag" runat="server" ErrorMessage="Tag description is required" ControlToValidate="txtAddTag" EnableViewState="false" SetFocusOnError="true">*</asp:RequiredFieldValidator>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="lbViewTag" runat="server" Text='<%# Bind("Description") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Parent Tag">
<EditItemTemplate>
<asp:DropDownList ID="ddlEditParentTag" runat="server" DataTextField="Description" DataValueField="TagId" AppendDataBoundItems="True" DataSourceID="odsParentTagsOnly" >
<asp:ListItem Text="[Parent]" Value="" />
</asp:DropDownList>
</EditItemTemplate>
<InsertItemTemplate>
<asp:DropDownList ID="ddlAddParentTag" runat="server" DataTextField="Description" DataValueField="TagId" AppendDataBoundItems="True" DataSourceID="odsParentTagsOnly" >
<asp:ListItem Text="[Parent]" Value="" />
</asp:DropDownList>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="lblParentTag" runat="server" Text='<%# (Eval("Tag") != null) ? ((SBI.ITService.DAL.EntityClasses.TagEntity)Eval("Tag")).Description : "" %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ButtonType="Button" ShowEditButton="True" ShowInsertButton="True" />
</Fields>
<PagerSettings Mode="NextPreviousFirstLast" />
<PagerStyle VerticalAlign="Bottom" />
<PagerTemplate>
<table>
<tr>
<td>
<asp:LinkButton CommandName="Page" runat="Server" CausesValidation="false" CommandArgument="First" ID="btnFirst" Text="<<" />
<asp:LinkButton CommandName="Page" runat="Server" CausesValidation="false" CommandArgument="Prev" ID="btnPrev" Text="<" />
<asp:LinkButton CommandName="Page" runat="Server" CausesValidation="false" CommandArgument="Next" ID="btnNext" Text=">" />
<asp:LinkButton CommandName="Page" runat="Server" CausesValidation="false" CommandArgument="Last" ID="btnLast" Text=">>" />
</td>
<td align="right">
Page <asp:Label ID="lblPage" runat="server" />
of <asp:Label ID="lblPages" runat="server" />
</td>
</tr>
</table>
</PagerTemplate>
</asp:DetailsView>
<asp:GridView ID="gvParentTags" runat="server" AutoGenerateColumns="False" DataKeyNames="TagId" DataSourceID="odsTags" ShowFooter="True" OnRowCommand="GridView_RowCommand">
<Columns>
<asp:BoundField DataField="Description" HeaderText="Parent Tag" ReadOnly="True">
<ItemStyle HorizontalAlign="Left" VerticalAlign="Top" />
</asp:BoundField>
<asp:TemplateField HeaderText="Child Tag">
<ItemStyle VerticalAlign="Top" HorizontalAlign="Left" />
<FooterStyle VerticalAlign="Top" HorizontalAlign="Left" />
<ItemTemplate>
<br />
<asp:GridView ID="gvChildTags" runat="server" ShowFooter="False" ShowHeader="False" DataKeyNames="TagId" DataSource='<%# Bind("Tag_") %>' AutoGenerateColumns="False" OnRowDeleting="gvChildTags_RowDeleting" OnRowCommand="GridView_RowCommand">
<Columns>
<asp:BoundField DataField="Description" ShowHeader="False" ReadOnly="true" ItemStyle-VerticalAlign="top" ItemStyle-HorizontalAlign="left" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnEditChild" runat="server" CausesValidation="False" CommandName="Select" CommandArgument='<%# Bind("TagId") %>' Text="Edit" />
<asp:Button ID="btnDeleteChild" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete" OnClientClick="return confirm('Are you sure you want to remove this tag descriptor?');" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnEditParent" runat="server" CausesValidation="False" CommandName="Select" CommandArgument='<%# Bind("TagId") %>' Text="Edit" />
<asp:Button ID="btnDeleteParent" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete" OnClientClick="return confirm('Are you sure you want to remove this tag descriptor?\nAny exsting children will become parent tags.');" />
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="btnAdd" runat="server" CausesValidation="False" CommandName="Add" Text="Add Tag" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<cc2:LLBLGenProDataSource2 ID="odsTags" runat="server" AdapterTypeName="SBI.ITService.DAL.DatabaseSpecific.DataAccessAdapter, SBI.ITService.DALDBSpecific" LivePersistence="False" DataContainerType="EntityCollection" EntityFactoryTypeName="SBI.ITService.DAL.FactoryClasses.TagEntityFactory, SBI.ITService.DAL" OnPerformGetDbCount="odsTags_PerformGetDbCount" OnPerformSelect="odsTags_PerformSelect" OnPerformWork="odsTags_PerformWork" />
<%--DataSource in Question--%>
<cc2:LLBLGenProDataSource2 ID="odsTags2" runat="server" AdapterTypeName="SBI.ITService.DAL.DatabaseSpecific.DataAccessAdapter, SBI.ITService.DALDBSpecific" LivePersistence="False" DataContainerType="EntityCollection" EntityFactoryTypeName="SBI.ITService.DAL.FactoryClasses.TagEntityFactory, SBI.ITService.DAL" OnPerformGetDbCount="odsTags2_PerformGetDbCount" OnPerformSelect="odsTags2_PerformSelect" OnPerformWork="odsTags2_PerformWork" />
<%--End--%>
<cc2:LLBLGenProDataSource2 ID="odsParentTagsOnly" runat="server" AdapterTypeName="SBI.ITService.DAL.DatabaseSpecific.DataAccessAdapter, SBI.ITService.DALDBSpecific" AllowDuplicates="False" DataContainerType="EntityCollection" EntityFactoryTypeName="SBI.ITService.DAL.FactoryClasses.TagEntityFactory, SBI.ITService.DAL" OnPerformSelect="odsParentTagsOnly_PerformSelect" LivePersistence="False" />
code behind
public partial class Configuration_Tag : System.Web.UI.Page
{
private DropDownList parentList
{
get
{
switch (dvTags.CurrentMode)
{
case DetailsViewMode.Edit:
return dvTags.Rows[1].FindControl("ddlEditParentTag") as DropDownList;
case DetailsViewMode.Insert:
return dvTags.Rows[1].FindControl("ddlAddParentTag") as DropDownList;
default:
return null;
}
}
}
private EntityCollection<TagEntity> tags = null;
protected void Page_Load(object sender, EventArgs e) {}
protected void odsTags_PerformSelect(object sender, PerformSelectEventArgs2 e)
{
getTags();
foreach (TagEntity tag in tags)
e.ContainedCollection.Add(tag);
}
protected void odsTags_PerformGetDbCount(object sender, PerformGetDbCountEventArgs2 e)
{
getTags();
foreach (TagEntity tag in tags)
e.ContainedCollection.Add(tag);
e.DbCount = e.ContainedCollection.Count;
}
protected void odsTags_PerformWork(object sender, PerformWorkEventArgs2 e)
{
List<UnitOfWorkElement2> deactivate = e.Uow.GetEntityElementsToDelete();
if (deactivate.Count > 0)
{
TagEntity tag = deactivate[0].Entity as TagEntity;
tag.Active = false;
e.Uow.RemoveFromUoW(tag);
e.Uow.AddForSave(tag);
}
e.Uow.Commit(new DataAccessAdapter(), true);
reBindDetail();
reBindList();
}
//
//OBJECT EVENTS IN QUESTION
//
protected void odsTags2_PerformSelect(object sender, PerformSelectEventArgs2 e)
{
getTags();
recurseThroughTags(tags, e.ContainedCollection);
}
protected void odsTags2_PerformGetDbCount(object sender, PerformGetDbCountEventArgs2 e)
{
getTags();
recurseThroughTags(tags, e.ContainedCollection);
e.DbCount = e.ContainedCollection.Count;
}
protected void odsTags2_PerformWork(object sender, PerformWorkEventArgs2 e)
{
TagEntity tag = null;
foreach (UnitOfWorkElement2 uow in e.Uow.GetEntityElementsToInsert())
{
tag = uow.Entity as TagEntity;
if (parentList.SelectedIndex != 0)
tag.ParentTagId = Convert.ToInt32(parentList.SelectedValue);
else
tag.ParentTagId = null;
}
foreach (UnitOfWorkElement2 uow in e.Uow.GetEntityElementsToUpdate())
{
tag = uow.Entity as TagEntity;
if (parentList.SelectedIndex != 0)
tag.ParentTagId = Convert.ToInt32(parentList.SelectedValue);
else
tag.ParentTagId = null;
}
e.Uow.Commit(new DataAccessAdapter(), true);
reBindGrid();
reBindList();
}
//
// END
//
protected void odsParentTagsOnly_PerformSelect(object sender, PerformSelectEventArgs2 e)
{
getTags();
foreach (TagEntity tag in tags)
e.ContainedCollection.Add(tag);//if (tag.TagId != Convert.ToInt32(dvTags.DataKey["TagId"])) e.ContainedCollection.Add(tag);
}
protected void GridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
switch (e.CommandName)
{
case "Select":
int index = 0;
foreach (TagEntity tag in odsTags2.EntityCollection)
{
if (tag.TagId == Convert.ToInt32(e.CommandArgument))
{
dvTags.PageIndex = index;
dvTags.ChangeMode(DetailsViewMode.Edit);
return;
}
index++;
}
break;
case "Add":
dvTags.ChangeMode(DetailsViewMode.Insert);
break;
}
}
protected void gvChildTags_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int PK = Convert.ToInt32(((GridView)sender).DataKeys[e.RowIndex]["TagId"]);
TagEntity tag = new TagEntity(PK);
tag.Active = false;
tag.IsNew = false;
using (DataAccessAdapter da = new DataAccessAdapter()) { da.SaveEntity(tag); }
reBindGrid();
reBindDetail();
reBindList();
}
protected void dvTags_DataBound(object sender, EventArgs e)
{
//page x of y
DetailsViewRow pagerRow = dvTags.BottomPagerRow;
if (pagerRow != null)
{
Label pageNum = pagerRow.FindControl("lblPage") as Label;
Label totalNum = pagerRow.FindControl("lblPages") as Label;
int page = dvTags.DataItemIndex + 1;
pageNum.Text = page.ToString();
totalNum.Text = dvTags.DataItemCount.ToString();
}
if (parentList != null && dvTags.DataKey["ParentTagId"] != null) parentList.SelectedValue = dvTags.DataKey["ParentTagId"].ToString();
}
private void recurseThroughTags(EntityCollection<TagEntity> nestedTags, IEntityCollection2 ret)
{
foreach (TagEntity tag in nestedTags)
{
ret.Add(tag);
if (tag.Tag_ != null) recurseThroughTags(tag.Tag_, ret);
}
}
private void reBindGrid()
{
odsTags.Refetch = true;
gvParentTags.DataBind();
}
private void reBindDetail()
{
odsTags2.Refetch = true;
dvTags.DataBind();
}
private void reBindList()
{
odsParentTagsOnly.Refetch = true;
if(parentList != null) parentList.DataBind();
}
private void getTags()
{
if (tags == null)
{
tags = new EntityCollection<TagEntity>(new TagEntityFactory());
IRelationPredicateBucket bucket = new RelationPredicateBucket();
bucket.PredicateExpression.Add(TagFields.Active == true);
bucket.PredicateExpression.AddWithAnd(TagFields.ParentTagId == DBNull.Value);
bucket.Relations.Add(TagEntity.Relations.TagEntityUsingTagIdParentTagId, "Child", JoinHint.Left);
SortExpression sort = new SortExpression();
sort.Add((TagFields.Description | SortOperator.Ascending));
sort[0].CaseSensitiveCollation = false;
IPrefetchPath2 prefetchPath = new PrefetchPath2((int)EntityType.TagEntity);
IPrefetchPathElement2 pathElement = TagEntity.PrefetchPathTag_;
pathElement.Filter.Add(TagFields.Active == true);
pathElement.Sorter.Add((TagFields.Description | SortOperator.Ascending));
pathElement.Sorter[0].CaseSensitiveCollation = false;
prefetchPath.Add(pathElement);
using (DataAccessAdapter da = new DataAccessAdapter()) { da.FetchEntityCollection(tags, bucket, 0, sort, prefetchPath); }
}
}
Any ideas on what I may be doing wrong?
This is with insert AND update or just with insert? It's a bit cumbersome to track what's going on, the GridView gvParentTags apparently isn't showing the parents, but the children, as the datasourcecontrol in question is bound to the other one.
Joined: 05-Jul-2006
This is only happening with updates. Insert works fine.
gvParentTags binds to odsTags. It displays the records correctly with parents and children. The delete and select (button reads "edit") work correctly as well. dvTags is a list of all the tags children and parents on the same "plain" (not nested). The sort is: 0. parent 1 1. child 1 of parent 1 2. child 2 of parent 1 3. parent 2 4. child 1 of parent 2 5. child 2 of parent 2 6. parent 3
When dvTags is in edit mode it will only update indexes 1, 2, 4 & 5. It will not update 0,3 or 6.
Joined: 05-Jul-2006
version: 2.0.0.60717 LLBLGen Pro .NET 2.0 ORM Support Classes Library 2.0.0.60712 LLBLGen Pro .NET 2.0 Dynamic Query Engine for SqlServer (7/2000/2005/MSDE)
The updates are not propagated to the DB. The PreformWork event is never triggered for an entity with an original parent_tag_id = null. That's what doesn't make sense if fires when the original parent_tag_id is not null.
You made a mistake in the detailsview. You've specified: DataKeyNames="TagId,ParentTagId"
which is wrong, as ParentTagId isn't a PK field. Remove ParentTagId from DataKeyNames, it will then work.
The reason it fails is because the datasourcecontrol will receive the key fields and the values they have for the entity to update. It will then try to find the entity using these fields and values in the bound collection. This fails. With the proper PK field names in DataKeyNames it does work.