创建 类PetShop4.0 架构的项目 (一) DAL层

本文介绍PetShop项目的架构设计,包括数据库访问层(DAL)的创建过程。从DBUtility类到Model实体类,再到IDAL接口定义及具体实现,最后通过抽象工厂模式统一管理数据库操作。
部署运行你感兴趣的模型镜像

PetShop是微软公司提供的一个巨大而复杂的玩具。MSDN上说,这个架构可以扩展成N层架构。虽然觉得这话有自诩的成分在其中,但是在看完整个代码后,不得不承认,这个PetShop还真是个复杂的“玩具”。

那就玩玩好了,试着自己创建了一个。这里记录下:

按照习惯,还是从DAL层开始创建。依照以下顺序创建项目:

1、DBUtility

        这个是数据库访问的基础,包含对应SqlServer的访问类SqlHelper和对应Oracle的访问类OracleHelper。创建好后,直接把PetShop中的两个类Ctrl+C过来就好。嘿嘿,我是很懒的。要注意的是这里使用了ConfigurationManager类来读取配置文件中的连接字符串

        //数据库连接字符串
        public static readonly string ConnectionStringLocalTransaction = ConfigurationManager.ConnectionStrings["SQLConnString1"].ConnectionString;
        
public static readonly string ConnectionStringInventoryDistributedTransaction = ConfigurationManager.ConnectionStrings["SQLConnString2"].ConnectionString;
        
public static readonly string ConnectionStringOrderDistributedTransaction = ConfigurationManager.ConnectionStrings["SQLConnString3"].ConnectionString;
        
public static readonly string ConnectionStringProfile = ConfigurationManager.ConnectionStrings["SQLProfileConnString"].ConnectionString;        

要在配置文件中提供相应的配置信息才能够运行。顺便说下,PetShop中的数据库分为4个:
MSPetShop4——PetShop信息库,存储商品信息,供应商信息等基础信息
MSPetShop4Orders——订单库,存储订单信息
MSPetShop4Profiles——用户信息库,存储用户信息、购物车信息等
MSPetShop4Services——服务信息库,存储各种应用程序信息,dll路径等。
上面的四个连接,就分别对应这四个数据库

2、Model

        这个是系统的实体类,按照自己的业务实体创建实体类吧。一般来说,我们的实体类有可能会用到Soap这样的协议中去,所以支持序列化还是必要的。不复杂,直接在类的头上加上[Serializable]这个特性描述就好。如:

    /// <summary>
    
/// 订单业务实体
    
/// </summary>
    [Serializable]
    
public class OrderInfo {

        
// 成员变量
        private int orderId;
        
private DateTime date;
        
private string userId;
        
private CreditCardInfo creditCard;
        
private AddressInfo billingAddress;
        
private AddressInfo shippingAddress;
        
private decimal orderTotal;
        
private LineItemInfo[] lineItems;
        
private Nullable<int> authorizationNumber;

        
/// <summary>
        
/// 默认构造方法
        
/// WebService 的序列化机制需要
        
/// </summary>
        public OrderInfo() { }

        
/// <summary>
        
/// 带初始值的构造方法
        
/// </summary>
        
/// <param name="orderId">主键</param>
        
/// <param name="date">订货日期</param>
        
/// <param name="userId">订货人(编号)</param>
        
/// <param name="creditCard">订货信用卡</param>
        
/// <param name="billing">订货地址</param>
        
/// <param name="shipping">送货地址</param>
        
/// <param name="total">订单价值</param>
        
/// <param name="line">订单商品(数组)</param>
        
/// <param name="authorization">信用卡注册号</param>
        public OrderInfo(int orderId, DateTime date, string userId, CreditCardInfo creditCard, AddressInfo billing, AddressInfo shipping, decimal total, LineItemInfo[] line, Nullable<int> authorization) {
            
this.orderId = orderId;
            
this.date = date;
            
this.userId = userId;
            
this.creditCard = creditCard;
            
this.billingAddress = billing;
            
this.shippingAddress = shipping;
            
this.orderTotal = total;
            
this.lineItems = line;
            
this.authorizationNumber = authorization;
        }

        
// 属性
        public int OrderId {
            
get { return orderId; }
            
set { orderId = value; }
        }

        
public DateTime Date {
            
get { return date; }
            
set { date = value; }
        }

        
public string UserId {
            
get { return userId; }
            
set { userId = value; }
        }

        
public CreditCardInfo CreditCard {
            
get { return creditCard; }
            
set { creditCard = value; }
        }

        
public AddressInfo BillingAddress {
            
get { return billingAddress; }
            
set { billingAddress = value; }
        }

        
public AddressInfo ShippingAddress {
            
get { return shippingAddress; }
            
set { shippingAddress = value; }
        }

        
public decimal OrderTotal {
            
get { return orderTotal; }
            
set { orderTotal = value; }
        }

        
public LineItemInfo[] LineItems {
            
get { return lineItems; }
            
set { lineItems = value; }
        }

        
public Nullable<int> AuthorizationNumber {
            
get {return authorizationNumber;}
            
set {authorizationNumber = value;}
        }
    }

要注意的是需要一个默认构造方法,即使你没有使用它。因为在WebService中如果序列化这个实体,需要这个默认构造

3、IDAL

        从这里开始我们要开始添加引用了。这里我们要使用到之前建立的实体类,所以引用Model
        PetShop中使用了抽象工厂模式,所以,现在我们要创建接口了。对应每个Model中的实体创建各自的接口。还是拿Order来说,创建如下的类:

    /// <summary>
    
/// DAL中订单对象接口
    
/// </summary>
    public interface IOrder {

        
/// <summary>
        
/// 插入订单
        
/// </summary>
        
/// <param name="order">订单业务实体</param>
        
/// <returns>订单编号</returns>
        void Insert(OrderInfo order);

        
/// <summary>
        
/// 按订单ID, 获取订单信息
        
/// </summary>
        
/// <param name="orderId">订单ID</param>
        
/// <returns>订单业务实体</returns>
        OrderInfo GetOrder(int orderId);
    }

一般来说,接口中包含的方法,就是在外部要使用的那些方法了,所以这里开始就和业务的逻辑有些相关了。要决定如何使用。如在PetShop中针对商品(Item)类就是如下建立接口的:
    /// <summary>
    
/// DAL中商品对象接口
    
/// </summary>
    public interface IItem{
        
        
/// <summary>
        
/// 按产品ID, 获取商品对象
        
/// </summary>
        
/// <param name="productId">产品ID</param>
        
/// <returns>商品实体类集合接口</returns>
        IList<ItemInfo> GetItemsByProduct(string productId);

        
/// <summary>
        
/// 按商品ID, 获取商品信息
        
/// </summary>
        
/// <param name="itemId">商品ID</param>
        
/// <returns>商品业务实体</returns>
        ItemInfo GetItem(string itemId);
    }


4、SQLServerDAL/OracleDAL

        好了,可以针对数据库创建各自的具体数据库访问和命令执行了。要用到之前的所有项目,所以引用吧。这里需要引用DBUtility、Model、IDAL
       
针对不同的实体创建类吧,要实现之前针对实体创建的接口才行,还是拿Order来说,如下:
5、DALFactory

    public class Order : IOrder {

        
//静态常量,T-SQL语句,参数名等
        private const string SQL_INSERT_ORDER = "Declare @ID int; Declare @ERR int; INSERT INTO Orders VALUES(@UserId, @Date, @ShipAddress1, @ShipAddress2, @ShipCity, @ShipState, @ShipZip, @ShipCountry, @BillAddress1, @BillAddress2, @BillCity, @BillState, @BillZip, @BillCountry, 'UPS', @Total, @BillFirstName, @BillLastName, @ShipFirstName, @ShipLastName, @AuthorizationNumber, 'US_en'); SELECT @ID=@@IDENTITY; INSERT INTO OrderStatus VALUES(@ID, @ID, GetDate(), 'P'); SELECT @ERR=@@ERROR;";
        
private const string SQL_INSERT_ITEM = "INSERT INTO LineItem VALUES( ";
        
private const string SQL_SELECT_ORDER = "SELECT o.OrderDate, o.UserId, o.CardType, o.CreditCard, o.ExprDate, o.BillToFirstName, o.BillToLastName, o.BillAddr1, o.BillAddr2, o.BillCity, o.BillState, BillZip, o.BillCountry, o.ShipToFirstName, o.ShipToLastName, o.ShipAddr1, o.ShipAddr2, o.ShipCity, o.ShipState, o.ShipZip, o.ShipCountry, o.TotalPrice, l.ItemId, l.LineNum, l.Quantity, l.UnitPrice FROM Orders as o, lineitem as l WHERE o.OrderId = @OrderId AND o.orderid = l.orderid";
        
private const string PARM_USER_ID = "@UserId";
        
private const string PARM_DATE = "@Date";
        
private const string PARM_SHIP_ADDRESS1 = "@ShipAddress1";
        
private const string PARM_SHIP_ADDRESS2 = "@ShipAddress2";
        
private const string PARM_SHIP_CITY = "@ShipCity";
        
private const string PARM_SHIP_STATE = "@ShipState";
        
private const string PARM_SHIP_ZIP = "@ShipZip";
        
private const string PARM_SHIP_COUNTRY = "@ShipCountry";
        
private const string PARM_BILL_ADDRESS1 = "@BillAddress1";
        
private const string PARM_BILL_ADDRESS2 = "@BillAddress2";
        
private const string PARM_BILL_CITY = "@BillCity";
        
private const string PARM_BILL_STATE = "@BillState";
        
private const string PARM_BILL_ZIP = "@BillZip";
        
private const string PARM_BILL_COUNTRY = "@BillCountry";
        
private const string PARM_TOTAL = "@Total";
        
private const string PARM_BILL_FIRST_NAME = "@BillFirstName";
        
private const string PARM_BILL_LAST_NAME = "@BillLastName";
        
private const string PARM_SHIP_FIRST_NAME = "@ShipFirstName";
        
private const string PARM_SHIP_LAST_NAME = "@ShipLastName";
        
private const string PARM_AUTHORIZATION_NUMBER = "@AuthorizationNumber";  
        
private const string PARM_ORDER_ID = "@OrderId";
        
private const string PARM_LINE_NUMBER = "@LineNumber";
        
private const string PARM_ITEM_ID = "@ItemId";
        
private const string PARM_QUANTITY = "@Quantity";
        
private const string PARM_PRICE = "@Price";

        
/// <summary>
        
/// 插入一个订单
        
/// </summary>
        
/// <param name="order">OrderInfo订单</param>

        public void Insert(OrderInfo order) {
            StringBuilder strSQL 
= new StringBuilder();

            
//获取每个command的parameter数组
            SqlParameter[] orderParms = GetOrderParameters();

            SqlCommand cmd 
= new SqlCommand();

            
// 初始化参数(parameter)
            orderParms[0].Value = order.UserId;
            orderParms[
1].Value = order.Date;
            orderParms[
2].Value = order.ShippingAddress.Address1;
            orderParms[
3].Value = order.ShippingAddress.Address2;
            orderParms[
4].Value = order.ShippingAddress.City;
            orderParms[
5].Value = order.ShippingAddress.State;
            orderParms[
6].Value = order.ShippingAddress.Zip;
            orderParms[
7].Value = order.ShippingAddress.Country;
            orderParms[
8].Value = order.BillingAddress.Address1;
            orderParms[
9].Value = order.BillingAddress.Address2;
            orderParms[
10].Value = order.BillingAddress.City;
            orderParms[
11].Value = order.BillingAddress.State;
            orderParms[
12].Value = order.BillingAddress.Zip;
            orderParms[
13].Value = order.BillingAddress.Country;
            orderParms[
14].Value = order.OrderTotal;
            orderParms[
15].Value = order.BillingAddress.FirstName;
            orderParms[
16].Value = order.BillingAddress.LastName;
            orderParms[
17].Value = order.ShippingAddress.FirstName;
            orderParms[
18].Value = order.ShippingAddress.LastName;
            orderParms[
19].Value = order.AuthorizationNumber.Value;

            
foreach (SqlParameter parm in orderParms)
                cmd.Parameters.Add(parm);

            
// 创建数据库连接
            using (SqlConnection conn = new SqlConnection(SqlHelper.ConnectionStringOrderDistributedTransaction)) {

                
// 插入订单状态
                strSQL.Append(SQL_INSERT_ORDER);
                SqlParameter[] itemParms;
                
// 循环所购商品项, 插入订单
                int i = 0;
                
foreach (LineItemInfo item in order.LineItems) {
                    strSQL.Append(SQL_INSERT_ITEM).Append(
" @ID").Append(", @LineNumber").Append(i).Append(", @ItemId").Append(i).Append(", @Quantity").Append(i).Append(", @Price").Append(i).Append("); SELECT @ERR=@ERR+@@ERROR;");

                    
//取得缓存的参数(parameter)
                    itemParms = GetItemParameters(i);

                    itemParms[
0].Value = item.Line;
                    itemParms[
1].Value = item.ItemId;
                    itemParms[
2].Value = item.Quantity;
                    itemParms[
3].Value = item.Price;
                    
//向command中加入参数
                    foreach (SqlParameter parm in itemParms)
                        cmd.Parameters.Add(parm);
                    i
++;
                }


                conn.Open();
                cmd.Connection 
= conn;
                cmd.CommandType 
= CommandType.Text;
                cmd.CommandText 
= strSQL.Append("SELECT @ID, @ERR").ToString();

                
// 读取查询返回, 应该是返回错误数量
                using (SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) {
                    
// 读取返回的 @ERR
                    rdr.Read();
                    
// 如果错误数量不为0则throw一个异常
                    if (rdr.GetInt32(1!= 0)
                        
throw new ApplicationException("DATA INTEGRITY ERROR ON ORDER INSERT - ROLLBACK ISSUED");
                }

                
//清除command中的参数数组
                cmd.Parameters.Clear();
            }

        }


        
/// <summary>
        
/// 从数据库中读取一个订单
        
/// </summary>
        
/// <param name="orderId">订单编号</param>
        
/// <returns>所有订单的信息</returns>

        public OrderInfo GetOrder(int orderId) {

            OrderInfo order 
= new OrderInfo();

            
//创建参数
            SqlParameter parm = new SqlParameter(PARM_ORDER_ID, SqlDbType.Int);
            parm.Value 
= orderId;

            
//执行查询读取订单
            using (SqlDataReader rdr = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringOrderDistributedTransaction, CommandType.Text, SQL_SELECT_ORDER, parm)) {

                
if (rdr.Read()) {

                    
//从第一行中读出订单头
                    AddressInfo billingAddress = new AddressInfo(rdr.GetString(5), rdr.GetString(6), rdr.GetString(7), rdr.GetString(8), rdr.GetString(9), rdr.GetString(10), rdr.GetString(11), rdr.GetString(12), null"email");
                    AddressInfo shippingAddress 
= new AddressInfo(rdr.GetString(13), rdr.GetString(14), rdr.GetString(15), rdr.GetString(16), rdr.GetString(17), rdr.GetString(18), rdr.GetString(19), rdr.GetString(20), null"email");

                    order 
= new OrderInfo(orderId, rdr.GetDateTime(0), rdr.GetString(1), null, billingAddress, shippingAddress, rdr.GetDecimal(21), nullnull);

                    IList
<LineItemInfo> lineItems = new List<LineItemInfo>();
                    LineItemInfo item 
= null;

                    
//根据第一行及其子行创建商品列表
                    do {
                        item 
= new LineItemInfo(rdr.GetString(22), string.Empty, rdr.GetInt32(23), rdr.GetInt32(24), rdr.GetDecimal(25));
                        lineItems.Add(item);
                    }
 while (rdr.Read());

                    order.LineItems 
= new LineItemInfo[lineItems.Count];
                    lineItems.CopyTo(order.LineItems, 
0);
                }

            }


            
return order;
        }


        
/// <summary>
        
/// 获取缓存参数的内部方法
        
/// </summary>
        
/// <returns></returns>

        private static SqlParameter[] GetOrderParameters() {
            SqlParameter[] parms 
= SqlHelper.GetCachedParameters(SQL_INSERT_ORDER);

            
if (parms == null{
                parms 
= new SqlParameter[] {
                    
new SqlParameter(PARM_USER_ID, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_DATE, SqlDbType.DateTime, 12),
                    
new SqlParameter(PARM_SHIP_ADDRESS1, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_SHIP_ADDRESS2, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_SHIP_CITY, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_SHIP_STATE, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_SHIP_ZIP, SqlDbType.VarChar, 50),
                    
new SqlParameter(PARM_SHIP_COUNTRY, SqlDbType.VarChar, 50),
                    
new SqlParameter(PARM_BILL_ADDRESS1, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_BILL_ADDRESS2, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_BILL_CITY, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_BILL_STATE, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_BILL_ZIP, SqlDbType.VarChar, 50),
                    
new SqlParameter(PARM_BILL_COUNTRY, SqlDbType.VarChar, 50),
                    
new SqlParameter(PARM_TOTAL, SqlDbType.Decimal, 8),
                    
new SqlParameter(PARM_BILL_FIRST_NAME, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_BILL_LAST_NAME, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_SHIP_FIRST_NAME, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_SHIP_LAST_NAME, SqlDbType.VarChar, 80),
                    
new SqlParameter(PARM_AUTHORIZATION_NUMBER, SqlDbType.Int)}
;

                SqlHelper.CacheParameters(SQL_INSERT_ORDER, parms);
            }


            
return parms;
        }


        
private static SqlParameter[] GetItemParameters(int i) {
            SqlParameter[] parms 
= SqlHelper.GetCachedParameters(SQL_INSERT_ITEM + i);

            
if (parms == null{
                parms 
= new SqlParameter[] {
                    
new SqlParameter(PARM_LINE_NUMBER + i, SqlDbType.Int, 4),
                    
new SqlParameter(PARM_ITEM_ID+i, SqlDbType.VarChar, 10),
                    
new SqlParameter(PARM_QUANTITY+i, SqlDbType.Int, 4),
                    
new SqlParameter(PARM_PRICE+i, SqlDbType.Decimal, 8)}
;

                SqlHelper.CacheParameters(SQL_INSERT_ITEM 
+ i, parms);
            }


            
return parms;
        }

    }

 

        好了,万事俱备,只欠工厂了。这个项目就是传说中的抽象工厂了,需要引用IDAL
        代码非常简单,如下:
        好了,一个简单的抽象工厂模式下的DAL层这里就算建好了。我们在BusinessLogic层次中只需要引用DALFactory、IDAL、Model就可以使用了。直接使用DALFactory中的Create方法创建实例,然后调用其方法就可以实现对数据库的增删查改。
        至于,在PetShop中还提供了的Message机制和Membership机制就下次再讨论了。

  /// <summary>
    
/// 抽象工厂类, 从配置文件创建DAL
    
/// </summary>

    public sealed class DataAccess {

        
// 从配置文件获取我们要使用的DAL类型
        private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];
        
private static readonly string orderPath = ConfigurationManager.AppSettings["OrdersDAL"];
        
        
private DataAccess() { }

        
/// <summary>
        
/// 创建目录访问对象实例
        
/// </summary>
        
/// <returns>目录接口实例</returns>

        public static PetShop.IDAL.ICategory CreateCategory() {
            
//依照配置文件, 取得类名
            string className = path + ".Category";
            
//反射调用, 根据数据库不同创建不同对象
            return (PetShop.IDAL.ICategory)Assembly.Load(path).CreateInstance(className);
        }


        
/// <summary>
        
/// 创建存货访问对象实例
        
/// </summary>
        
/// <returns>存货接口实例</returns>

        public static PetShop.IDAL.IInventory CreateInventory() {
            
string className = path + ".Inventory";
            
return (PetShop.IDAL.IInventory)Assembly.Load(path).CreateInstance(className);
        }


        
/// <summary>
        
/// 创建商品访问对象实例
        
/// </summary>
        
/// <returns>商品接口实例</returns>

        public static PetShop.IDAL.IItem CreateItem() {
            
string className = path + ".Item";
            
return (PetShop.IDAL.IItem)Assembly.Load(path).CreateInstance(className);
        }


        
/// <summary>
        
/// 创建订单访问对象实例
        
/// </summary>
        
/// <returns>订单接口实例</returns>

        public static PetShop.IDAL.IOrder CreateOrder() {
            
string className = orderPath + ".Order";
            
return (PetShop.IDAL.IOrder)Assembly.Load(orderPath).CreateInstance(className);
        }


        
/// <summary>
        
/// 创建产品访问对象实例
        
/// </summary>
        
/// <returns>产品接口实例</returns>

        public static PetShop.IDAL.IProduct CreateProduct() {
            
string className = path + ".Product";
            
return (PetShop.IDAL.IProduct)Assembly.Load(path).CreateInstance(className);
        }


    }

您可能感兴趣的与本文相关的镜像

Llama Factory

Llama Factory

模型微调
LLama-Factory

LLaMA Factory 是一个简单易用且高效的大型语言模型(Large Language Model)训练与微调平台。通过 LLaMA Factory,可以在无需编写任何代码的前提下,在本地完成上百种预训练模型的微调

、Model主要功能: 1、 将每个“业务实体”抽象成“(瘦数据)”,可以很好地“划分”各个“对象”,操作更加清晰 2、 用于在应用程序各之间传递数据,被用做传输数据的“容器” 3、 这就是所谓的“建模”过程! 4、 Model各个(Model文件夹中的各个文件)划分或者说编制的原则,更趋向于模拟整个系统中的业务实体 二、实现细节: 1、 PetShop中Model的规划与数据库表的关系: (1) AccountInfo——Account表 (2) AddressInfo——无直接对应关系(对应Account表中部分字段) (3) CartItemInfo——无直接对应关系 (4) CreditCardInfo——无直接对应关系 (5) ItemInfo——Item表 (6) LineItemInfo——无直接对应关系 (7) OrderInfo——Orders表 (8) ProductInfo——Product表 2、 为每个Model中的都标记了[Serializable],说明这些可以被传行化,但是不能被继承! 3、 AccountInfo.cs文件:用户在网站注册的信息,及喜好选择情况 4、 使用构造函数可以初始化私有字段;使用属性可以读取私有字段(但使用属性不能设置私有字段的值) 5、 其中包含个AddressInfo的私有变量,和个AddressInfo的属性 6、 命名空间为PetShop.Model 7、 AddressInfo.cs文件:用户真实的个人姓名、住址和电话号码等信息 8、 与AccountInfo不同的是,AddressInfo允许使用属性设置私有变量的值 9、 CartItemInfo.cs文件:描述购物车中每种所选商品的信息的 10、 该“”对象的某些信息(如这里的Subtotal属性)可能并不是此的“自然信息”,而需要经过简单计算而得到!这些简单但必要的信息也要在的设计中体现出来! 11、 CreditCardInfo.cs文件:表示特定张信用卡的信息 12、 ItemInfo.cs文件:个Item指的是category"product"item,如猫"波斯猫"成年男波斯猫(或成年女波斯猫)。这个文件表示个Item的所有信息 13、 productDesc字段的作用? 14、 LineItemInfo.cs文件:注意与CartItemInfo的区别!LineItemInfo是用来描述用户最终确认的订单当中的某的产品的信息的 15、 同样包括了Subtotal属性 16、 OrderInfo.cs文件:用于显示用户某个订单具体信息的,在此个订单当中,可能包括多个商品种,即包括多个LineItemInfo对象(实际上在OrderInfo中也确实存在LineItemInfo型对象的个数组!) 17、 ProductInfo.cs文件:包括个特定Product的信息,如波斯猫 三、启发: 1、 来自Directory项目结束后的启发,以后做设计的时候,要将每个实体抽象为,在整个系统中进行操作。 2、 在任意当中,可能不只包括此实体的自然信息,也可以包括些对其他地方数据调用有用的属性信息,如根据数量和单价计算出来的总价属性,或者标志此实体的直属上级实体的属性 四、问题: 1、 忽然发现在MSDN上有文章,关于数据实体的:浏览 2、 抽象这些业务实体模型为瘦数据的原则是什么?什么样的业务实体可以被抽象,或者说进行抽象后更有意义? 3、 ItemInfo中,productDesc字段的作用? 、IDAL主要功能: 1、 这完全是“工厂模式”的部分实现而已 2、 这是组接口,其中包括了每个要公开的数据访问方法。为每个数据库产品单独编写的DAL(数据访问)都要实现这组接口所定义的方法 3、 也就是规定了在DAL中编写的“对用户账号进行操作的”所必须执行的方法! 4、 IDAL要达到的目的是:实现业务逻辑(BLL)与数据库访问(DAL)的完全分离!!! 5、 IDAL各个(IDAL文件夹中的各个文件)划分或者说编制的原则,更趋向于“将对数据库的不同操作进行归”,考虑的主要方面是数据库操作!!!例如,有对用户账号进行的系列数据库操作,则将这系列操作统放置于IAccount接口(将来实现后的Account)文件当中 二、实现细节: 1、 IAccount.cs文件:为针对不同数据库产品编写的“操作用户账号的”所必须实现的系列方法定义契约 2、 IInventory.cs文件:定义“操作库存量的”所必须实现的系列方法;或者说将操作库存量的系列(所有)方法做个汇总 3、 IItem.cs文件:定义“操作某Item的”所必须实现的系列方法。(Item在Model中定义了,是指具体某别的Product,如男猫或女猫) 4、 对于其中的GetItemsByProduct()方法,返回的是个ArrayList的接口型(IList)的对象(见问题部分!) 5、 IOrder.cs文件:定义了DAL中“操作用户订单的”必须执行的方法。其中包括“添加张新订单”的方法Insert()和根据个已有的订单号取得此订单详细信息的方法GetOrder(),此方法返回的是个OrderInfo对象。(Model中的OrderInfo模型定义了用户的某张Order中相关的信息,如发货地点,总价,信用卡号码等等) 6、 IProduct.cs文件:定义组在DAL中编写的“对Product进行操作的” 7、 IProfile.cs文件:定义组在DAL编写的“对用户Profile进行操作的” 三、启发: 1、 这样就可以让在BLL只针对IDAL定义的接口进行编程(使用IDAL接口定义的这些方法)就可以了!!!无论在底使用了什么厂家的数据库产品,有区别的只是针对此数据库产品编写的DAL(相同的方法,如SignIn()方法,对于不同的数据库产品,可能有不同的实现方式!),而不会影响到上的BLL已经编写好的内容! 2、 从这里可以看到软件架构师和程序员工作上的区别!架构师要负责的是搭建系统的次结构,定义接口;而程序员要负责的是针对接口的具体代码实现过程! 3、 这个IDAL接口的使用,主要是为了保证在底数据库实现,甚至数据库产品发生变化的时候,不需要对上BLL的业务逻辑进行大量的修改!BLL针对IDAL接口编程即可!!! 4、 IDAL文件夹中定义的所有的接口中的所有的方法,包括了整个程序要对数据库进行操作的所有方法 5、 由于PetShop只是个演示程序,所以若对数据库操作的某别(如对Account进行操作)中定义的“操作”不够用(如除了接口中定义的几个方法外还需要其他Account操作),还可以在接口中追加其他的方法,用以约束DAL的实现(如Account)必须执行这些新增加的方法! 四、问题: 1、 定义这组接口后,如何保证为每个单独的数据库产品编写的DAL都执行这组接口所定义的方法?(答案:编写DAL的时候必须刻意保证,否则就失去了定义IDAL分割BLL和DAL的意义!!!) 2、 既然在实现GetItemsByProduct()方法的时候,也是要把返回的所有Item对象添加到个ArrayList当中去,但为什么GetItemsByProduct()方法返回的不是个ArrayList对象,而是个IList接口的对象呢?仅仅是基引用的方法吗?这里的基引用有什么用呢?是否是由于为了不限制使用的数组形式?执行IList则可以使用ArrayList,也可以使用其他形式的数组??? 3、 IProduct.cs文件中为何要将查询条件参数定义为string型的数组?
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值