2way databinding composite objects

Posts   
 
    
ltemple
User
Posts: 4
Joined: 07-Aug-2007
# Posted on: 07-Aug-2007 23:55:09   

I am using the LLBL version 2.0.0.0 Demo.
I have an employee entity and an address entity. My employee has a foreign key to the address. Very simple one to one sample. These are my only 2 tables I am using for the sample of the LLBLDataSource. I have the VS solution built and I have created a web page to display a list of employees in a grid view. I have the grid view bound to the LLBLGenProDatasource. This gives me the 2 way binding and allows edit of the employee. What i want to do is show the employee's city and zip in the same row on the grid view. how do i bind this information about the employee in this data grid without having the user have to select and then go to an employee update page. this is just a sample of binding and not necessarily any real world scenario here but simple enought to prove the point. Any help is appreciated. Lynette

goose avatar
goose
User
Posts: 392
Joined: 06-Aug-2007
# Posted on: 08-Aug-2007 00:40:51   

Hi Lynette , to do that you simply have to do:

  1. Indicate to LLBLGenDataSource that prefetch Address Entity.
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        IPrefetchPath2 path = new PrefetchPath2((int)EntityType.EmployeeEntity);
        path.Add(EmployeeEntity.PrefetchPathAddress);

        // here use your LLBLGenDataSource object name
        this._employeeDS.PrefetchPathToUse = path;
    }               
}

  1. Delete AddressId column from your GridView and add these ones:
<asp:TemplateField HeaderText="City" ItemStyle-CssClass="ColumnContent" ItemStyle-Wrap="false" HeaderStyle-CssClass="tableheaders" HeaderStyle-HorizontalAlign="Left" HeaderStyle-Wrap="false">
    <ItemTemplate>
        <asp:Label ID="City" runat="server" Text='<%# Eval("Address.City") %>'/>
    </ItemTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText="ZIP" ItemStyle-CssClass="ColumnContent" ItemStyle-Wrap="false" HeaderStyle-CssClass="tableheaders" HeaderStyle-HorizontalAlign="Left" HeaderStyle-Wrap="false">
    <ItemTemplate>
        <asp:Label ID="City" runat="server" Text='<%# Eval("Address.Zip") %>'/>
    </ItemTemplate>
</asp:TemplateField>

No tested but should works. Tell me if everything in ok with that wink

ltemple
User
Posts: 4
Joined: 07-Aug-2007
# Posted on: 08-Aug-2007 01:32:31   

That did display the city and zip for me as you posted. Thank you. Do you know if there is a limitation here that will not allow me to bind these (2 way) so that either of these values could be edited right here? Thanks for your help

goose avatar
goose
User
Posts: 392
Joined: 06-Aug-2007
# Posted on: 08-Aug-2007 02:05:19   

I believe this should work: just add this below the ItemTemplate closing tag...

<EditItemTemplate>
    <asp:TextBox
        ID="CityEdit" 
        runat="server" 
        Text='<%# Bind("Address.City") %>'>
    </asp:TextBox>
</EditItemTemplate>
ltemple
User
Posts: 4
Joined: 07-Aug-2007
# Posted on: 08-Aug-2007 02:20:22   

This is what i came up with prior to sending my previous message

<asp:TemplateField HeaderText="City" ItemStyle-CssClass="ColumnContent" ItemStyle-Wrap="false" HeaderStyle-CssClass="tableheaders" HeaderStyle-HorizontalAlign="Left" HeaderStyle-Wrap="false"> <EditItemTemplate> <asp:TextBox ID="CityEdit" runat="server" Text='<%# Bind("Address.City") %>'> </asp:TextBox> </EditItemTemplate> </asp:TemplateField>

This seems similar to yours. however, it does not matter which one i use for both of them i do not get a clean build .. my error

A call to Bind was not well formatted.

Any suggestions as to what is wrong.... it looks like the samples in the online docs to me

thanks!

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 08-Aug-2007 06:15:50   

Following goose's post these are the final list of steps:

**1. **Indicate to LLBLGenDataSource that prefetch Address Entity.

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        IPrefetchPath2 path = new PrefetchPath2((int)EntityType.EmployeeEntity);
        path.Add(EmployeeEntity.PrefetchPathAddress);

        // here use your LLBLGenDataSource object name
        this._employeeDS.PrefetchPathToUse = path;
    }               
}

2. Create Entity Custom Properties for ZIP and City fields on EmployeeEntity.cs USER_REGION:

// __LLBLGENPRO_USER_CODE_REGION_START CustomEntityCode

public virtual System.String City
{
    get
    {
        if (this.Address != null)
        {
            return this.Address.City;
        }
        else
        {
            return (System.String)TypeDefaultValue.GetDefaultValue(typeof(System.String));
        }
    }
    set
    {
        if (this.Address != null)
        {
            this.Address.City = value;
        }
    }
}


///...
///... same for ZIP


// __LLBLGENPRO_USER_CODE_REGION_END

3. Delete AddressId column from your GridView declarative code and add these ones: (note that here your are binding your already created custom property City and ZIP.

<asp:TemplateField HeaderText="City" ItemStyle-CssClass="ColumnContent" ItemStyle-Wrap="false" HeaderStyle-CssClass="tableheaders" HeaderStyle-HorizontalAlign="Left" HeaderStyle-Wrap="false">

    <EditItemTemplate>                      
        <asp:TextBox
            ID="CityEdit"
            runat="server"
            Text='<%# Bind("City") %>'>
        </asp:TextBox>                                                                                  
    </EditItemTemplate>

    <ItemTemplate>
        <asp:Label ID="City" runat="server" Text='<%# Bind("City") %>'/>
    </ItemTemplate>

</asp:TemplateField>

///...
///... same for ZIP

**4. **As LLBLGenProDataSource won't save recursively the changes made in AddressEntity, you need to:

**4.1.** Set **_yourLLBLGenProDataSource.LivePersistence = false**;

**4.2.** Add a handler for **_yourLLBLGenProDataSource.PerformSelect

**

protected void _yourLLBLGenProDataSource_PerformSelect(object sender, SD.LLBLGen.Pro.ORMSupportClasses.PerformSelectEventArgs2 e)
{
     using (DataAccessAdapter adapter = new DataAccessAdapter())
     {
          adapter.FetchEntityCollection(e.ContainedCollection, e.Filter, e.MaxNumberOfItemsToReturn, e.Sorter, e.PrefetchPath, e.PageNumber, e.PageSize);
     }
}
**4.2.** Add a handler for** _yourLLBLGenProDataSource.PerformWork**
protected void ldsProducts_PerformWork(object sender, PerformWorkEventArgs e)
{
    // needed for know the product entities that will be upated
    e.Uow.ConstructSaveProcessQueues();
    System.Collections.Generic.List<UnitOfWorkElement2> updateEntityList = e.Uow.GetEntityElementsToUpdate();

    // for each product entity add its related supplier to the save queue
    foreach (UnitOfWorkElement2 ouwe in updateEntityList)
    {
        if (((EmployeeEntity)ouwe.Entity).Address != null && ((EmployeeEntity)ouwe.Entity).Address.IsDirty)
        {
            e.Uow.AddForSave(((EmployeeEntity)ouwe.Entity).Address);
        }
    }

    // finally.. save uow (containing EnpolyeeEntity and its related AddressEntity
    using (DataAccessAdapter adapter = new DataAccessAdapter))
    {
        e.Uow.Commit(adapter, true);
    }
}

This would seems cumbersome, but once you make it, it would be a piece of cake in future times. Please let us know if everything is clear and helpul wink

Regards.

David Elizondo | LLBLGen Support Team
ltemple
User
Posts: 4
Joined: 07-Aug-2007
# Posted on: 09-Aug-2007 00:17:08   

this works. thanks for having such a responsive support forum

yj
User
Posts: 39
Joined: 07-Aug-2007
# Posted on: 22-Aug-2007 09:15:03   

hi, could anyone help about this statement IPrefetchPath path = new PrefetchPath((int)EntityType.MyGroupEntity);

the error i got is EntityType does not exist in this context am i missing out any library inclusion here? thanks

p/s: I am using LLBLGen Pro, SelfServicing and C#

Thanks

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 22-Aug-2007 09:30:03   

I think you are missing:

using <yourProjectNamespaceRoot>;

Can you confirm that? please post the _using _section of your file.

(Note: for future posts, please open a new thread when the issue doen't correspond to the thread title [Databinding and Gui controls in this case wink ])

Cheers.

David Elizondo | LLBLGen Support Team
yj
User
Posts: 39
Joined: 07-Aug-2007
# Posted on: 22-Aug-2007 10:16:23   

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 SBVS.CollectionClasses; using SBVS.EntityClasses; using SBVS.TypedListClasses; using SBVS.HelperClasses; using SBVS.RelationClasses;

this is the using section i have however, i cant get the EntityType class using intellisense, nor can i compile my thing if it is included

thanks

yj
User
Posts: 39
Joined: 07-Aug-2007
# Posted on: 22-Aug-2007 11:01:36   

daelmo wrote:

I think you are missing:

using <yourProjectNamespaceRoot>;

Can you confirm that? please post the _using _section of your file.

(Note: for future posts, please open a new thread when the issue doen't correspond to the thread title [Databinding and Gui controls in this case wink ])

Cheers.

hi daelmo, u r rite thanks problems solved

Posts: 2
Joined: 18-Sep-2007
# Posted on: 18-Sep-2007 20:47:13   

daelmo wrote:

Following goose's post these are the final list of steps: 2. Create Entity Custom Properties for ZIP and City fields on EmployeeEntity.cs USER_REGION:

Hi Daelmo,

I believe your solution would work, but it would be IMHO pretty dirty. Imagine the results in a solution with a great number of entities and gridviews. Having to redefine all the children's properties on all parents wouldn't be a good solution to me.

If anyone has a solution that can navigate relationships properly without recreating all sub properties, and is true two way databinding between the grid and the collection (meaning you get the updates in the EntityCollection if the data is modified), I'd be quite interested.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 19-Sep-2007 18:02:39   

RenaudMartinon wrote:

Hi Daelmo,

I believe your solution would work, but it would be IMHO pretty dirty. Imagine the results in a solution with a great number of entities and gridviews. Having to redefine all the children's properties on all parents wouldn't be a good solution to me.

If anyone has a solution that can navigate relationships properly without recreating all sub properties, and is true two way databinding between the grid and the collection (meaning you get the updates in the EntityCollection if the data is modified), I'd be quite interested.

You can find a detailed answer for your question in the following thread: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=11239