自定义可绑定数据的业务对象实体和强类型-Part Three

步骤二 : 创建自定义业务层


第一件要做的事情,就是添加一个新的工程文件到我们的解决方案中,再次,它的类型是一个类库,命名为"DCAF.BusinessLayer".


因为我们的自定义业务对象应该被告知去哪里取他们的数据,因为这一点,我们应该添加一个到DCAF.DataLayer集合的引用.这个可以简单地通过在工程文件夹中选择"引用",然后右击,选择"添加引用",转到"工程(译注:俺的IDE版本显示的是'项目')"页签,选择图6所示的集合.


图6.添加集合引用到工程中


下一步,添加两个类到工程中,命名为"CustomerBO"(持有Customer的定义)和"OrderBO"(持有Order的定义).


using System;
using System.Collections.Generic;
using System.Text;
using DCAF.DataLayer;
using DCAF.DataLayer.CustomerOrderTDSTableAdapters;

namespace DCAF.BusinessLayer
{
    
public class CustomerBO
    
{
        
private string m_CustomerId;
        
private string m_CompanyName;
        
private List<OrderBO> m_Orders = new List<OrderBO>();

        
public string CustomerId
        
{
            
get return m_CustomerId; }
            
set { m_CustomerId = value; }
        }


        
public string CompanyName
        
{
            
get return m_CompanyName; }
            
set { m_CompanyName = value; }
        }


        
public List<OrderBO> Orders
        
{
            
get return m_Orders; }
        }

    }

}


顾客业务对象类包含2个属性,一个是它的ID,一个是它的Name,一个存储订单(列表)的集合.同时注意到这里DCAF.DataLayer的引用,我们会在一分钟内返回来这里.


using System;
using System.Collections.Generic;
using System.Text;

namespace DCAF.BusinessLayer
{
    
public class OrderBO
    
{
        
private int m_OrderId;
        
private string m_ProductName;
        
private CustomerBO m_Customer;
        
private DateTime m_OrderDate;

        
public int OrderId
        
{
            
get return m_OrderId; }
            
set { m_OrderId = value; }
        }


        
public string ProductName
        
{
            
get return m_ProductName; }
            
set { m_ProductName = value; }
        }


        
public CustomerBO Customer
        
{
            
get return m_Customer; }
            
set { m_Customer = value; }
        }


        
public DateTime OrderDate
        
{
            
get return m_OrderDate; }
            
set { m_OrderDate = value; }
        }

    }

}


另一方面,订单表也包含了一些属性值和一个指向它所属的顾客的引用.


最后...我们应该实现我们的O/R映射功能,用数据来填实我们的顾客业务对象!为此,我已经实现了另一个方法(代码部分的下面有解释).方法应该被添加到CustomerBO类中!


public static List<CustomerBO> GetCustomerOrders()
{
    
//--- Create the DataService
    CustomerOrderService dataService = new CustomerOrderService();

    CustomerOrderTDS dataContainer;
    dataContainer 
= new CustomerOrderTDS();

    
//--- Create the DataContainer for Customers and Orders retrieval
    dataContainer.Merge(dataService.GetCustomerOrders());

    
//--- Create a CustomerObject List to hold the Customers
    List<CustomerBO> customerList = new List<CustomerBO>();

    
//--- Loop through the CustomerData from our DataContainer
    foreach (CustomerOrderTDS.CustomersRow customerRow in dataContainer.Customers.Rows)
    
{
        
//--- Create a Customer Object Instance
        CustomerBO customer = new CustomerBO();

        
//--- Map the Relational data to Object properties 
        
//for Customer
        ORM.RelationalToObject(customer, customerRow);

        
//--- Select the Related Orders of the Customer
        CustomerOrderTDS.OrdersRow[] orderRows =
                (CustomerOrderTDS.OrdersRow[])customerRow.GetChildRows(
"FK_Orders_Customers");

        
//--- Loop through the related OrderData for the 
        
// Current Customer
        int numOrder = 0;
        
foreach (CustomerOrderTDS.OrdersRow orderRow in orderRows)
        
{
            numOrder
++;

            
//--- Create an Order Object Instance
            OrderBO order = new OrderBO();

            
//--- Map the Relational data to Object 
            
//properties for Order
            ORM.RelationalToObject(order, orderRow);

            
//--- Add the Customer Reference to the Order
            order.Customer = customer;

            order.ProductName 
= string.Format("Product {0}-{1}", order.OrderId, numOrder);

            
//--- Relate the Order to The Current Customer
            customer.Orders.Add(order);
        }

        customerList.Add(customer);
    }

    
return customerList;
}


因此,我们创建一个叫做"GetCustomerOrders"的静态方法,返回一个顾客对象列表(注意:你也可以使用List的泛型匹配,List<T>).首先,我们通过我们的强类型中的数据服务抓取数据.然后,我们循环遍历Customer的数据容器行,添加Customer信息,为Orders得到子行,添加Order信息,最后,添加Customer对象到List中.


为了简化O/R映射任务,我已经添加一个ORM类到工程中.该类有两个方法,一个用于映射关系数据到对象属性(叫做ORM.RelationalToObject),另一个用于保持对象时将属性映射回关系数据,这是一个动态的方式,因此,这两个方法可以在任何"表/对象"(table/object)映射的场景.下面的代码演示了RelationalToObject映射方法.相反的方法将在我们描述我们的保持程序时解释.


public static void RelationalToObject(object p_obj, DataRow p_dataRow)
{
    
//--- Get Object Properties
    PropertyDescriptorCollection props = TypeDescriptor.GetProperties(p_obj);

    
//--- Apply OR-Mapping
    foreach (DataColumn column in p_dataRow.Table.Columns)
    
{
        
for (int propertyIndex = 0; propertyIndex < props.Count; propertyIndex++)
        
{
            PropertyDescriptor prop;
            
try
            
{
                prop 
= props[propertyIndex];
            }

            
catch
            
{
                
continue;
            }

            
//--- Omit IListTypes (childcollections)
            if (prop.PropertyType.GetInterface("IList"== null)
            
{
                
if (prop.Name.Trim().ToLower() == column.ColumnName.Trim().ToLower())
                
{
                    prop.SetValue(p_obj, p_dataRow[column]);
                }

            }

        }

    }

}

我们已经完成了业务层(BusinessLayer),值得提的是,正是为了该演示,我遵循一个非常基本的业务对象(BusinessObject)的部署规则,没有考虑到业务规则(BizzRules),缓存,属性修改消息(将在描述Save()部分时涉及)等等,因为那些部署已经超出本文的范围.

posted @ 2008-01-22 19:24 mickeysuda 阅读(...) 评论(...) 编辑 收藏