Binding ActiveRecord to a DataGrid in Read Only Mode

As I have been playing with ActiveRecord (http://www.castleproject.org ) one of the things I need to do was to bind a ActiveRecord class to a datagrid to view data. I did not need to worry about insert/update/delete in the grid.  So you may be saying big deal, this is easy. You are correct if you are just binding primitive types (int, string, etc). However, if your ActiveRecord class has any complex objects such as other ActiveRecord class then you can not by default get to the data by just setting the DataSource to the results of the FindAll() method.

To solve the databinding problem, I found ObjectDataSource worked really well.  On the datagrid I wanted to display a collection of WorkOrders and the Tool.ToolName value as a column. To get the workorders, I used the ActiveRecord FindAll() method.

ActiveRecord Class:

 

using System;

using System.Collections.Generic;

using System.Text;

using Castle.ActiveRecord;

 

namespace MyARDemo

{

    [ActiveRecord("WorkOrders")]

    [System.ComponentModel.DataObject]

    public partial class WorkOrder : DomainObject<WorkOrder>

    {

        private DateTime _createdOn;

        private string _createdOnShift;

        private string _createdOnWorkWeek;

        private string _description;

        private DateTime _lastUpdatedOn;

        private int _id;

        private Tool _tool;

        private User _createdByUser;

        private User _lastUpdatedByUser;

 

        public WorkOrder()

        {

        }

 

 

        [PrimaryKey(PrimaryKeyType.Native, "WorkOrderID", Access = PropertyAccess.FieldLowercaseUnderscore)]

        public int ID

        {

            get { return _id; }

            set { _id = value; }

        }

 

        [Property(NotNull = true, Column = "CreatedOn")]

        public DateTime CreatedOn

        {

            get { return _createdOn; }

            set { _createdOn = value; }

        }

 

        [Property(NotNull = true, Length = 2, Column = "CreatedOnShift")]

        public string CreatedOnShift

        {

            get { return _createdOnShift; }

            set { _createdOnShift = value; }

        }

 

        [Property(NotNull = true, Length = 6, Column = "CreatedOnWorkWeek")]

        public string CreatedOnWorkWeek

        {

            get { return _createdOnWorkWeek; }

            set { _createdOnWorkWeek = value; }

        }

 

        [Property(NotNull = true, SqlType = "VARCHAR(MAX)", Column = "Description")]

        public string Description

        {

            get { return _description; }

            set { _description = value; }

        }

 

        [Property(NotNull = true, Column = "LastUpdatedOn")]

        public DateTime LastUpdatedOn

        {

            get { return _lastUpdatedOn; }

            set { _lastUpdatedOn = value; }

        }

 

        [BelongsTo("ToolID")]

        public Tool Tool

        {

            get { return _tool; }

            set { _tool = value; }

        }

 

        [BelongsTo("CreatedByUserID")]

        public User CreatedByUser

        {

            get { return _createdByUser; }

            set { _createdByUser = value; }

        }

 

        [BelongsTo("LastUpdatedByUserID")]

        public User LastUpdatedByUser

        {

            get { return _lastUpdatedByUser; }

            set { _lastUpdatedByUser = value; }

        }

    }

}

 

using System;

using System.Collections.Generic;

using System.Text;

using Castle.ActiveRecord;

 

namespace MyARDemo

{

    [ActiveRecord("Tools")]

    public partial class Tool : DomainObject<Tool>

    {

        private bool _customized;

        private bool _deleted;

        private int _lastUpdatedByID;

        private DateTime _lastUpdatedOn;

        private string _toolName;

        private int _id;

        private IList<WorkOrder> _workOrders;

 

        public Tool()

        {

            _workOrders = new List<WorkOrder>();

        }

 

 

        [PrimaryKey(PrimaryKeyType.Native, "ToolID", Access = PropertyAccess.FieldLowercaseUnderscore)]

        public int ID

        {

            get { return _id; }

            set { _id = value; }

        }

 

        [Property(NotNull = true, Column = "Customized")]

        public bool Customized

        {

            get { return _customized; }

            set { _customized = value; }

        }

 

        [Property(NotNull = true, Column = "Deleted")]

        public bool Deleted

        {

            get { return _deleted; }

            set { _deleted = value; }

        }

 

        [Property(NotNull = true, Column = "LastUpdatedByID")]

        public int LastUpdatedByID

        {

            get { return _lastUpdatedByID; }

            set { _lastUpdatedByID = value; }

        }

 

        [Property(NotNull = true, Column = "LastUpdatedOn")]

        public DateTime LastUpdatedOn

        {

            get { return _lastUpdatedOn; }

            set { _lastUpdatedOn = value; }

        }

 

        [Property(NotNull = true, Length = 50, Column = "ToolName")]

        public string ToolName

        {

            get { return _toolName; }

            set { _toolName = value; }

        }

 

        [HasMany(typeof(WorkOrder), Lazy = true, Table = "WorkOrders", ColumnKey="ToolID", Inverse=true)]

        public IList<WorkOrder> WorkOrders

        {

            get { return _workOrders; }

            set { _workOrders = value; }

        }

    }

}

 

WebForm Code:

On the DataGrid, I left AutoGeneration on for the primitive types and for the complex type Tool.ToolName, I added a Templated Column.

<Columns>

     <asp:TemplateField HeaderText="Tool">

         <ItemTemplate>

             <asp:Label ID="Label1" runat="server" Text='<%# Eval("Tool.ToolName") %>'></asp:Label>

         </ItemTemplate>

     </asp:TemplateField>

</Columns>

 

I know that there is a ARDataSource project in the AR Contrib but it would not compile for me and since I did not need the more than a ReadOnly view I did not work to fix the errors. I may ultimately end up writing my own data source control. There are several articles that talk about how to do it and even some code from other ORM data source controls.

Nikhil Kothari's Weblog : Data Source Controls Summary: http://www.nikhilk.net/DataSourceControlsSummary.aspx

Vault of Thoughts - .NET Blog - How To Use MyObjectDataSource: http://vaultofthoughts.net/HowToUseMyObjectDataSource.aspx

NHibernateDataSource: A DataSourceControl for ASP.NET 2.0 - The Code Project - ASP.NET: http://www.codeproject.com/useritems/NHibernateDataSource.asp

Paul Wilson's .NET Blog : Introducing the WilsonORMapper DataSource Control: http://weblogs.asp.net/pwilson/archive/2006/05/17/446919.aspx


Related posts

Comments

February 7. 2007 11:46 AM

Michal Talaga

As the author of the mentioned data source control (MyObjectDataSource) I can only say that when you will be writing your own you will have 2 choices: either make the interface similar to the one on the ObjectDataSource (I have taken this approach) and make the control easier to use for someone who already knows ASP.NET or you can make it right Smile
Doing it right means for example not using the TypeName and DataObjectTypeName properties, which until this day I have problems telling which one which. And there are also lots of other problems with a standard interface, but you will see when you get there Smile
Happy coding.

Michal Talaga

Add comment


(Will show your Gravatar icon)  

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

November 21. 2008 08:41 PM