Search code examples
c#asp.netfluent-nhibernatefluent-nhibernate-mapping

Displaying nhiberbate components in asp.net


I'm working on an ASP.NET/C#/fluent nHibernate project and have recently discovered the Component mapping feature that I would like to implement. I believe I have my class definitions and mapping file correct, but I am having difficulty retrieving the component information with my service and/or repository layers to display it in a DetailsView or FormView.

When I use an ObjectDataSource to retrieve the information, the aspx code that is generated in the corresponding view puts the whole component in a TextBox:

<asp:TextBox ID="extraTextBox" runat="server" Text='<%# Bind("extra") %>' />

I have found numerous resources online of how to do the mapping itself, but haven't been able to find more guidance on properly displaying the component pieces. Any guidance would be appreciated!

// Stripped down classes
public partial class ProjectExtra
{
    private int _test1;
    private int _test2;

    public ProjectExtra() {}

    public virtual int test1 { get { return this._test1; } set { this._test1 = value; } }
    public virtual int test2 { get { return this._test2; } set { this._test2 = value; } }
}

public partial class Project
{
    private int _pkProjectID;
    private ProjectExtra _extra;

    public Project() {}

    public virtual ProjectExtra extra
    {
        get
        {
            return this._extra;
        }
        set
        {
            this._extra = value;
        }
    }
    public virtual int pkProjectID
    {
        get
        {
            return this._pkProjectID;
        }
        set
        {
            this._pkProjectID = value;
        }
    }
}

// stripped down mapping
public class ProjectMap : ClassMap<Project>
{
    public ProjectMap()
    {
        Table(@"Project");
        LazyLoad();
        Id(x => x.pkProjectID)
          .Column("pkProjectID")
          .Access.Property()
          .Not.Nullable()
          .GeneratedBy.Identity();

        Component<ProjectExtra>(x => x.extra, m =>
        {
            // JobsCreatedActual and JobsCreatedEstimate are two integer columns
            // in the Project database table
            m.Map(x => x.test1).Column("JobsCreatedActual");
            m.Map(x => x.test2).Column("JobsCreatedEstimate");
            Not.LazyLoad();
        });
    }
}

Solution

  • To do this, I ended up using the following format:

    <asp:TextBox ID="extraTextBox" runat="server" 
    Text='<%# Eval("extra.test1") %>' />
    

    I have seen other resources using the full DataBinder, though the results seem to be the same:

    <asp:TextBox ID="extraTextBox" runat="server" 
    Text='<%# DataBinder.Eval(Container.DataItem, "test1"))%>' />
    

    Unfortunately, Bind does not work with subclasses, so they still need to be constructed in code-behind using TextBox values, etc.