网上有的资料说Profile这是个数据访问层,但我觉得不是,因为数据访问层要有数据的基本操作吧,如insert等。其二,这个明明是业务逻辑层的,因为它即加载了
BLL层,有加载了DAL层的ProfileDALFactory这个抽象工厂即其接口类。所以我先判定其为BLL层的。
首先Profile这个类继承了微软类ProfileProvider,下面就来说说第一个困惑吧:
2
3 string username = ( string )context[ " UserName " ]; // 获取用户名
4 bool isAuthenticated = ( bool )context[ " IsAuthenticated " ]; // 判断是否匿名登录
5
6 SettingsPropertyValueCollection svc = new SettingsPropertyValueCollection();
7
8 foreach (SettingsProperty prop in collection) {
9 SettingsPropertyValue pv = new SettingsPropertyValue(prop);
10
11 switch (pv.Property.Name) {
12 case PROFILE_SHOPPINGCART: // 如果属性名是购物车
13 pv.PropertyValue = GetCartItems(username, true );
14 break ;
15 case PROFILE_WISHLIST: // 清单
16 pv.PropertyValue = GetCartItems(username, false );
17 break ;
18 case PROFILE_ACCOUNT: // 账户信息
19 if (isAuthenticated)
20 pv.PropertyValue = GetAccountInfo(username);
21 break ;
22 default :
23 throw new ApplicationException(ERR_INVALID_PARAMETER + " name. " );
24 }
25
26 svc.Add(pv);
27 }
28 return svc;
29 }
这个对继承类ProfileProvider.GetProPertyValue函数进行重写,传了两个值,一个是描述当前应用程序的用法,一个是属性的集合
看看程序的第十三行,pv.ProPertyValue:获取或设置 SettingsProperty 对象的值。这边应该是通过 GetCartItems(username, true)方法来获得cart对象了
那么现在是不是该看下GetCartItems(username, true)这个方法实现了什么了?
2 Cart cart = new Cart(); // 声明一个BLL.Cart类
3 // isShoppingCart=true,applicationName=".NET Pet Shop 4.0"
4 foreach (CartItemInfo cartItem in dal.GetCartItems(username, applicationName, isShoppingCart)) {
5
6 cart.Add(cartItem); // 吧购物车的信息添加到Cart中
7 }
8 return cart; // 最后传出去的是一个购物车的业务逻辑程序
9 }
这个就要返回一个对象Cart。dal.GetCartItems(username, applicationName, isShoppingCart)类获得一个CartItemInfo这个实体类对象,
让后就看代码行6了,它就调用了cart.Add方法了,我上面有注释,是吧购物车信息添加到Cart中,但我不知道为什么要这样做,就是不知道为什么要把
购物车信息放在Cart中。但是,看看cart.Add(cartItem)这个类的这个添加函数吧,答案应该在这里面:
2 CartItemInfo cartItem;
3 if ( ! cartItems.TryGetValue(item.ItemId, out cartItem)) // 参数一item.ItemId是键值,如果Dictionary包含键值返回true,cartItem应该是返回的值,这里的话应该是ItemId,但我不明白cartItem怎么匹配ItemId?否则false。
4 cartItems.Add(item.ItemId, item); // 如果字典中不包含ItemId,将item.ItemId和item添加到词典中
5 else
6 cartItem.Quantity += item.Quantity; // 如果ItemId在字典中可以找到,就更新ItemId对应的宠物数量
7 }
我上面有做了详细的解释,对了,在Cart这个类中还有一个私有字段很重要:
这个定义了Dictionary这个字典,这个字典功能简单而强大。他可以存放对象信息等。
最后应该是吧Cart这个对象放在这个字典中,然后通过Cart传递给SettingsPropertyValue pv= new SettingsPropertyValue(prop);
这个pv.PropertyValue这个属性值了。
/**********************************************************************************************/
接下来看Profile.SetPropertyValues这个函数,刚刚是对PropertyValue进行了赋值,现在是要用这个PropertyValue的值了,看下面把:
2
3 string username = ( string )context[ " UserName " ];
4 CheckUserName(username);
5 bool isAuthenticated = ( bool )context[ " IsAuthenticated " ]; // 是否匿名登录
6 int uniqueID = dal.GetUniqueID(username, isAuthenticated, false , ApplicationName); // 通过dal调用抽象工厂生产的DAL实例
7 if (uniqueID == 0 )
8 uniqueID = dal.CreateProfileForUser(username, isAuthenticated, ApplicationName);
9
10 foreach (SettingsPropertyValue pv in collection) {
11
12 if (pv.PropertyValue != null ) {
13 switch (pv.Property.Name) {
14 case PROFILE_SHOPPINGCART:
15 SetCartItems(uniqueID, (Cart)pv.PropertyValue, true );
16 break ;
17 case PROFILE_WISHLIST:
18 SetCartItems(uniqueID, (Cart)pv.PropertyValue, false );
19 break ;
20 case PROFILE_ACCOUNT:
21 if (isAuthenticated)
22 SetAccountInfo(uniqueID, (AddressInfo)pv.PropertyValue);
23 break ;
24 default :
25 throw new ApplicationException(ERR_INVALID_PARAMETER + " name. " );
26 }
27 }
28 }
29
30 UpdateActivityDates(username, false );
31 }
我刚上面说了PropertyValue得到的是一个Cart对象,故这个也要把PropertyValue的值转换为Cart对象,也是因为这个才可以转换为Cart对象的。
同理,还是来看看行15这个SetCartItems这个函数吧:
dal.SetCartItems(uniqueID, cart.CartItems, isShoppingCart);
}
这就简单地调用了SQLProflieDAL中的SetCartItems函数了,那么它到底实现了什么呢?
2 string sqlDelete = " DELETE FROM Cart WHERE UniqueID = @UniqueID AND IsShoppingCart = @IsShoppingCart; " ;
3
4 SqlParameter[] parms1 = {
5 new SqlParameter( " @UniqueID " , SqlDbType.Int),
6 new SqlParameter( " @IsShoppingCart " , SqlDbType.Bit)};
7 parms1[ 0 ].Value = uniqueID;
8 parms1[ 1 ].Value = isShoppingCart;
9
10 if (cartItems.Count > 0 ) {
11
12 // update cart using SqlTransaction
13 string sqlInsert = " INSERT INTO Cart (UniqueID, ItemId, Name, Type, Price, CategoryId, ProductId, IsShoppingCart, Quantity) VALUES (@UniqueID, @ItemId, @Name, @Type, @Price, @CategoryId, @ProductId, @IsShoppingCart, @Quantity); " ;
14
15 SqlParameter[] parms2 = {
16 new SqlParameter( " @UniqueID " , SqlDbType.Int),
17 new SqlParameter( " @IsShoppingCart " , SqlDbType.Bit),
18 new SqlParameter( " @ItemId " , SqlDbType.VarChar, 10 ),
19 new SqlParameter( " @Name " , SqlDbType.VarChar, 80 ),
20 new SqlParameter( " @Type " , SqlDbType.VarChar, 80 ),
21 new SqlParameter( " @Price " , SqlDbType.Decimal, 8 ),
22 new SqlParameter( " @CategoryId " , SqlDbType.VarChar, 10 ),
23 new SqlParameter( " @ProductId " , SqlDbType.VarChar, 10 ),
24 new SqlParameter( " @Quantity " , SqlDbType.Int)};
25 parms2[ 0 ].Value = uniqueID;
26 parms2[ 1 ].Value = isShoppingCart;
27
28
29 SqlConnection conn = new SqlConnection(SqlHelper.ConnectionStringProfile);
30 conn.Open();
31 SqlTransaction trans = conn.BeginTransaction(IsolationLevel.ReadCommitted);
32
33 try {
34 SqlHelper.ExecuteNonQuery(trans, CommandType.Text, sqlDelete, parms1);
35
36 foreach (CartItemInfo cartItem in cartItems) {
37 parms2[ 2 ].Value = cartItem.ItemId;
38 parms2[ 3 ].Value = cartItem.Name;
39 parms2[ 4 ].Value = cartItem.Type;
40 parms2[ 5 ].Value = cartItem.Price;
41 parms2[ 6 ].Value = cartItem.CategoryId;
42 parms2[ 7 ].Value = cartItem.ProductId;
43 parms2[ 8 ].Value = cartItem.Quantity;
44 SqlHelper.ExecuteNonQuery(trans, CommandType.Text, sqlInsert, parms2);
45 }
46 trans.Commit();
47 }
48 catch (Exception e) {
49 trans.Rollback();
50 throw new ApplicationException(e.Message);
51 }
52 finally {
53 conn.Close();
54 }
55 }
56 else
57 // delete cart
58 SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionStringProfile, CommandType.Text, sqlDelete, parms1);
59 }
这个SQLProflieDAL.SetCartItems函数,实现了Delete和Insert的功能,期间还用到了事务。
注意到上面,我只对其中的一两个属性做说明,并没有全部一一解释。
上面SetPropertyValues函数的最后一行还有一个UpdateActivityDates(username, false);函数,那么他到底是实现了什么操作呢?
dal.UpdateActivityDates(username, activityOnly, applicationName);
}
2 DateTime activityDate = DateTime.Now;
3
4 string sqlUpdate;
5 SqlParameter[] parms;
6
7 if (activityOnly) {
8 sqlUpdate = " UPDATE Profiles Set LastActivityDate = @LastActivityDate WHERE Username = @Username AND ApplicationName = @ApplicationName; " ;
9 parms = new SqlParameter[]{
10 new SqlParameter( " @LastActivityDate " , SqlDbType.DateTime),
11 new SqlParameter( " @Username " , SqlDbType.VarChar, 256 ),
12 new SqlParameter( " @ApplicationName " , SqlDbType.VarChar, 256 )};
13
14 parms[ 0 ].Value = activityDate;
15 parms[ 1 ].Value = userName;
16 parms[ 2 ].Value = appName;
17
18 }
19 else {
20 sqlUpdate = " UPDATE Profiles Set LastActivityDate = @LastActivityDate, LastUpdatedDate = @LastUpdatedDate WHERE Username = @Username AND ApplicationName = @ApplicationName; " ;
21 parms = new SqlParameter[]{
22 new SqlParameter( " @LastActivityDate " , SqlDbType.DateTime),
23 new SqlParameter( " @LastUpdatedDate " , SqlDbType.DateTime),
24 new SqlParameter( " @Username " , SqlDbType.VarChar, 256 ),
25 new SqlParameter( " @ApplicationName " , SqlDbType.VarChar, 256 )};
26
27 parms[ 0 ].Value = activityDate;
28 parms[ 1 ].Value = activityDate;
29 parms[ 2 ].Value = userName;
30 parms[ 3 ].Value = appName;
31 }
32
33 SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionStringProfile, CommandType.Text, sqlUpdate, parms);
34
35 }
对用户的登录信息进行了修改。