UPDATE 2009-01-27:  Choosing a Service model over a domain model inside NetTiers for the Component Layer can also achieve this functionality, but is definitely good to know and great to work with ObjectDataSources.  Reduces the code required for a lot of tasks dramatically.

Of late I have been dabbling with CodeSmith and also the templates for NetTiers, also making my own templates which is fun, but does demand a lot of time to generate re-usable templates.  Well to me anyway.  Now I do like NetTiers, all apart from the Web Layer which are UI controls and also Data controls.  I enjoy making strong use of ObjectDataSources to highly reduce code and improve pages, and one of the things that struck me was, well where are the parameter-less constructors, which is what I need to use the object against an ObjecDataSource.

This actually is no big hurdle for a couple of reasons but mainly because NetTiers creates such a detailed Domain Model.  So what I need and also how to make light work of this using Code Smith again but with my own template.

I need 5 base methods which will encapsulate the basic CRUD operations oh and the object is RestaurantType, not an enum but a type, only because the client will want to add more down the line and I do not want to rebuild the assembly for such a trivial addition.

  1. IList<RestaurantType> GetRestaurantTypes(int index, int pageSize, string sort);
  2. int GetRestaurantTypesCount(int index, int pageSize, string sort);
    1. Although this count method accepts the same parameters, it does not use them, it is simply to comply with the rule that the ObjectDataSource's Select Count method must have the same method signature and the Select method itself.
  3. void AddRestaurantType(RestaurantType restaurantType)
  4. void UpdateRestaurantType(RestaurantType restaurantType)
  5. void DeleteRestaurantType(RestaurantType restaurantType)

Another nice tip here is to decorate your class and the methods with Data Attributes which identify the class and also the methods as suitable for binding against.  Only the first, third, fourth and fifth method need decorating as the count method is not applicable, so CRUD:

  1. Create : [DataObjectMethod(DataObjectMethodType.Insert)]
  2. Read : [DataObjectMethod(DataObjectMethodType.Select)]
  3. Update : [DataObjectMethod(DataObjectMethodType.Update)]
  4. Delete : [DataObjectMethod(DataObjectMethodType.Delete)]

Finally the class itself is also decorated with the following:

[DataObject]

So here is the code for the simple data object with which I can bind an ObjectDataSource to.

   [DataObject]
    public class CustomRestaurantTypeDataSource
    {
        public static TransactionManager CreateTransaction()
        {
            TransactionManager transactionManager = null;
            if (DataRepository.Provider.IsTransactionSupported)
            {
                transactionManager = DataRepository.Provider.CreateTransaction();
                transactionManager.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted);
            }
            return transactionManager;
        }

        [DataObjectMethod(DataObjectMethodType.Select)]
        public IList<RestaurantType> GetRestaurantTypes(int index, int pageSize, string sort)
        {
            int count = -1;
            TList<RestaurantType> restaurantTypes = DataRepository.RestaurantTypeProvider.GetPaged(index / pageSize, pageSize, out count);
            return restaurantTypes.ToList();
        }

        public int GetRestaurantTypesCount(int index, int pageSize, string sort)
        {
            int count = -1;
            DataRepository.RestaurantTypeProvider.GetPaged(out count);
            return count;
        }

        [DataObjectMethod(DataObjectMethodType.Insert)]
        public void AddRestaurantType(RestaurantType restaurantType)
        {
            using (TransactionManager tm = CreateTransaction())
            {
                DataRepository.RestaurantTypeProvider.Insert(tm, restaurantType);
                tm.Commit();
            }
        }

        [DataObjectMethod(DataObjectMethodType.Update)]
        public void UpdateRestaurantType(RestaurantType restaurantType)
        {
            using (TransactionManager tm = CreateTransaction())
            {
                DataRepository.RestaurantTypeProvider.Update(tm, restaurantType);
                tm.Commit();
            }
        }

        [DataObjectMethod(DataObjectMethodType.Delete)]
        public void DeleteRestaurantType(RestaurantType restaurantType)
        {
            using (TransactionManager tm = CreateTransaction())
            {
                DataRepository.RestaurantTypeProvider.Delete(tm, restaurantType);
                tm.Commit();
            }
        }
    }

I have then used this on my ObjectDataSource like the following:

    <asp:ObjectDataSource ID="RestaurantTypeDataSource" runat="server" 
        DataObjectTypeName="TM.Entities.RestaurantType" 
        DeleteMethod="DeleteRestaurantType" EnablePaging="True" 
        MaximumRowsParameterName="pageSize" 
        OldValuesParameterFormatString="original_{0}" 
        SelectCountMethod="GetRestaurantTypesCount" SelectMethod="GetRestaurantTypes" 
        StartRowIndexParameterName="index" 
        TypeName="TM.WebSite.CodeFiles.CustomRestaurantTypeDataSource" 
        UpdateMethod="UpdateRestaurantType">
        <SelectParameters>
            <asp:Parameter DefaultValue="0" Name="index" Type="Int32" />
            <asp:Parameter DefaultValue="10" Name="pageSize" Type="Int32" />
            <asp:Parameter Name="sort" Type="String" />
        </SelectParameters>
    </asp:ObjectDataSource>

In one of my next posts I will show how to make a pager control.  I do like the ASP.NET Pager control but I really feel it lacks one thing, and that being a PageChangedEvent.  In the pager I will make, you will be able to set the TotalNumberOfPages and also subscribe to the PageChanged Event.  I feel this is quite useful and we could also write in code to handle any IPageableContainers brought in with the .NET 3.5 wave.

Cheers,


Andrew


Friday, January 16, 2009 8:26:44 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer