当前位置:编程学习 > C#/ASP.NET >>

初学三层结构,写了个代码,大家帮忙看看,顺便给小弟的问题指点一下。谢谢了

数据库中有张用户信息表(UserInfo),功能很简单,就是在页面上显示所有用户信息,和注册用户信息。

Web:只有一个Default.aspx页面,负责显示信息,和插入信息。
BLL: UserInfo.cs  负责检查用户在页面的输入和调用DAL的方法。
DAL:SQLHelper.cs 负责查询用户信息和插入新用户的信息到表。
Model:UserEntity.cs 用户实体类。

Web引用:BLL、DAL、Model。
BLL引用:DAL、Model。
DAL引用:Model。

================================================================================================
Web Default.aspx代码
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using BLL;
using Model;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            //调用BLL
            UserInfo userInfo = new UserInfo();
            GridView1.DataSource = userInfo.GetALLUserInfo();
            GridView1.DataBind();
        }

    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        

        //调用BLL层
        UserInfo userInfo = new UserInfo();
        if (!userInfo.CheckUserName(txtUserName.Text))
        {
            Label1.Text = "用户名过长或为空";
            return;
        }
        if (!userInfo.CheckSex(ddlSex.SelectedValue))
        {
            Label1.Text = "请选择性别";
            return;
        }
        if (!userInfo.CheckEmail(txtEmail.Text))
        {
            Label1.Text = "Email地址过长";
            return;
        }
        if (!userInfo.CheckPhone(txtPhone.Text))
        {
            Label1.Text = "电话号码过长";
            return;
        }
        if (!userInfo.CheckAddress(txtAddress.Text))
        {
            Label1.Text = "地址过长";
            return;
        }

        if (userInfo.Insert())
        {
            Label1.Text = "向数据表写入成功";
        }
        else
        {
            Label1.Text = "向数据表写入失败";
        }

    }
}

-----------------------------------------------------
BLL UserInfo.cs代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using DAL;
using Model;

namespace BLL
{
    public class UserInfo
    {
        UserEntity userEntity = new UserEntity();

        public bool CheckUserName(string UserName)
        {
            if (UserName.Length > 20 || UserName == "")
            {
                return false;
            }
            userEntity.UserName = UserName;
            return true;
        }

        public bool CheckSex(string Sex)
        {
            userEntity.Sex = Sex;
            return true;
        }

        public bool CheckEmail(string Email)
        {
            if (Email.Length > 50)
            {
                return false;
            }
            userEntity.Email = Email;
            return true;
        }

        public bool CheckPhone(string Phone)
        {
            if (Phone.Length > 20)
            {
                return false;
            }
            userEntity.Phone = Phone;
            return true;
        }

        public bool CheckAddress(string Address)
        {
            if (Address.Length > 50)
            {
                return false;
            }
            userEntity.Address = Address;
            return true;
        }

        public DataSet GetALLUserInfo()
        {
            SQLHelper sqlHelper = new SQLHelper();
            return sqlHelper.GetAllUserInfo();
        }

        public bool Insert()
        {
            return new SQLHelper().Insert(userEntity);
        }

    }
}

-------------------------------------------------
DAL SQLHelper.cs代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Model;

namespace DAL
{
    public class SQLHelper
    {
        public DataSet GetAllUserInfo()
        {
            string strSQL = "Select * From UserInfo";
            SqlConnection con = new SqlConnection("Data Source = (local);Integrated Security = SSPI;Initial Catalog = DBFile;");
            SqlDataAdapter da = new SqlDataAdapter(strSQL, con);
            DataSet ds = new DataSet();
            da.Fill(ds, "UserInfo");
            return ds;
        }

        public bool Insert(UserEntity userEntity)
        {
            string UserName = userEntity.UserName;
            string Sex = userEntity.Sex;
            string Email = userEntity.Email;
            string Phone = userEntity.Phone;
            string Address = userEntity.Address;

            string strSQL = "Insert Into UserInfo Values('" + UserName + "','" + Sex + "','" + Email + "','" + Phone + "','" + Address + "')";
            SqlConnection con = new SqlConnection("Data Source = (local);Integrated Security = SSPI;Initial Catalog = DBFile;");
            SqlCommand com = new SqlCommand(strSQL, con);
            try
            {
                con.Open();
                com.ExecuteNonQuery();
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                con.Close();
            }
        }
    }
}

-----------------------------------------
Model UserEntity.cs代码

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

namespace Model
{
    public class UserEntity
    {
        private string _UserName;
        private string _Sex;
        private string _Email;
        private string _Phone;
        private string _Address;

        public UserEntity() { }
        public UserEntity(string UserName, string Sex, string Email, string Phone, string Address)
        {
            this._UserName = UserName;
            this._Sex = Sex;
            this._Email = Email;
            this._Phone = Phone;
            this._Address = Address;
        }
        public string UserName
        {
            set { _UserName = value; }
            get { return _UserName; }
        }
        public string Sex
        {
            set { _Sex = value; }
            get { return _Sex; }
        }
        public string Email
        {
            set { _Email = value; }
            get { return _Email; }
        }
        public string Phone
        {
            set { _Phone = value; }
            get { return _Phone; }
        }
        public string Address
        {
            set { _Address = value; }
            get { return _Address; }
        }

    }
}

================================================================
我的问题
一:我这算算三层结构?
二:各个层的引用对吗?有没有多余或缺少的?
三:我看网上很多都用SQLHelper这个名字,我也不知道SQLHelper这里面的内用是不是和我写的这个差不多?
四:听人说用接口创建对象,我不明白,接口是个契约,里面不都是定义的函数吗,怎么能用接口创建对象呢,拜托给说说。
五:还请各位高手给说说还应该注意什么问题。 --------------------编程问答-------------------- http://www.asp.net/learn/dataaccess/tutorial01cs.aspx?tabid=63     DAL
http://www.asp.net/learn/dataaccess/tutorial02cs.aspx?tabid=63     BLL

--------------------编程问答-------------------- @_@ --------------------编程问答-------------------- 偶觉得初学还没必要过于考究架构的细节,了解理论,慢慢体会~

SQLHelper相当于一把瑞士军刀,提供的只是便利而以,跟三层结构没有太大关系~ --------------------编程问答-------------------- 一:我这算算三层结构?
========
算,类 Petshop .net 和 Java POJO 型

二:各个层的引用对吗?有没有多余或缺少的?
========

相对三层来说,没有,
然而,通常需要一个系统框架层或者一个实用通用层,它跨所有的层,提供各个层需要系统的公共服务,例如你可能常见的以 SystemFramework 或者 Common  命名的项目

三:我看网上很多都用SQLHelper这个名字,我也不知道SQLHelper这里面的内用是不是和我写的这个差不多?
==========
不是,你见到的应该是经典意义的 SqlHelper, 其实它是封装 ADO.NET 基本操作的一个实用类,它为整个 DAL 服务,而你这个 SqlHelper 只为 User 服务,也许你会说,我可以往其中加入其他 Entity 的 CRUD 操作,那么也不是,

比较经典的,应该是酱紫

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Model;

using DBUtility; // -> SqlHelper

namespace DAL
{
public class SQLHelper
{
public DataSet GetAllUserInfo()
{
string strSQL = "Select * From UserInfo";
//SqlConnection con = new SqlConnection("Data Source = (local);Integrated Security = //SSPI;Initial Catalog = DBFile;");
//SqlDataAdapter da = new SqlDataAdapter(strSQL, con);
//DataSet ds = new DataSet();
//da.Fill(ds, "UserInfo");
string strSQL = "Select * From UserInfo";
SqlConnection con = SqlHelper.CreateConnection();
DataSet ds = SqlHelper.ExecuteDataSet(con, strSql);
return ds;
}

public bool Insert(UserEntity userEntity)
{
string UserName = userEntity.UserName;
string Sex = userEntity.Sex;
string Email = userEntity.Email;
string Phone = userEntity.Phone;
string Address = userEntity.Address;

string strSQL = "Insert Into UserInfo Values('" + UserName + "','" + Sex + "','" + Email + "','" + Phone + "','" + Address + "')";
SqlConnection conn = SqlHelper.CreateConnection();
//SqlConnection con = new SqlConnection("Data Source = (local);Integrated Security = //SSPI;Initial Catalog = DBFile;");
//SqlCommand com = new SqlCommand(strSQL, con);
try
{
//con.Open();
//com.ExecuteNonQuery();
int affectedRecords = SqlHelper.ExecuteNonQuery(strSQL);
// 根据实际需要,是否检查返回的实际操作影响的行数
// return (affectedRecords > 0)
return true;
}
catch
{
// 应该丢出异常,由高层捕获处理
throw; 
//return false;
}
finally
{
//con.Close();
}
}
}
return false;
}


--------------------编程问答-------------------- 我觉得这已经很不错了。 --------------------编程问答-------------------- 你可以详细到 SqlHelper 应该是个怎么样的,

其实它还是一个纯 ADO.NET ,不与具体的系统发生耦合的,

你可以去下载,随便 baidu 一个就出来了

当然,最新的应该是 Enterprise Library, 但是毕竟复杂了


四:听人说用接口创建对象,我不明白,接口是个契约,里面不都是定义的函数吗,怎么能用接口创建对象呢,拜托给说说。
===============
也许你听到的,应该是,面向接口编程,

比如,按你这里的设计,考虑到以后数据库移植或者数据持久化策略的变动
会在 DAL 和 BLL 中设计一个 IDAL,DAL 实现 IDAL 中定义的接口,
那么,也许你最初客户要求数据库选择的是MS SQL Server,可以实现一个 SQLServerDAL, 
后来,某种商业或业务需求的原因,客户觉得 Oracle 比较合适,这时候,你只要实现一个 OracleDAL,取代原来的 SQLServerDal, 
或者,你的系统目标就是多套数据库支持,那么一般这样设计的,

而上层 BLL UI 都不需要做变化,或者变化是很小的(通过配置)

我不举例了,你下个 Petshop 3 (最新的是 4.0, 但是建议你从 3.0 开始,4.0 搞得态复杂了),下来看看就知道了

五:还请各位高手给说说还应该注意什么问题。
==========
实在太多了,不是纸上谈兵可以说清楚的,
主要是由于,没有实践,你不会有感触,
从实践中去慢慢深刻体会吧,

Good Luck!

--------------------编程问答-------------------- 关注,帮顶 --------------------编程问答-------------------- Jinglecat(晓风残月 >> 问题需简洁,错误要详细) 
非常感谢

还有一个问题请教一下:
我在表现层,都是直接用txtUserName.Text....等等的值直接传到BLL层来做检测的,请问我能否在表现层把这个txtUserName等等,赋予给一个UserEntity对象,然后在BLL写一个函数,参数是UserEntity对象,然后在表现层直接将UserEntity对象转递给BLL去验证,可以吗?? --------------------编程问答-------------------- Mark --------------------编程问答-------------------- UP
--------------------编程问答-------------------- 验证的东西不一定要全放到业务层的,具体看项目而定.权衡使用
初学,已经很不错了 --------------------编程问答-------------------- mark --------------------编程问答-------------------- 都是直接用txtUserName.Text....等等的值直接传到BLL层来做检测的,请问我能否在表现层把这个txtUserName等等,赋予给一个UserEntity对象,然后在BLL写一个函数,参数是UserEntity对象

========

对了,这一点忘了,给你我的建议了

你的想法是合理的,

事实上,我是第一次看到你的 BLL 中 CheckXxx 这样的代码,感觉有点“怪”

其实,C# 的属性 set 访问器是一个最佳执行业务逻辑判断的地方,你没有必要在 BLL 中用 ChechXXX, 按你的设计是一个 BLL 实例只能对应一个 Entity 实例,

通常,我是这样设计的

// Model
public class UserEntity
{
// ...
public string UserName
{
get { return _UserName; }
set { 
// 执行业务逻辑检查
if (value.Length > 20 || String.IsNullOrEmpty(value))
{
  throw new Exception("用户名不合法。");
}
_UserName = value;
}
// ...

}

// BLL
namespace BLL
{
public class UserInfo
// ...
public bool Insert(UserEntity user) // 传递 UserEntity
{
return new UserDb.Insert(user);
}
// ...
}

也就是Entity/Model(实体对象,域模型) 作为数据实体在层雨层之间传递


Hope helpful! --------------------编程问答-------------------- 1. 不要用字符串拼接语句..用参数

2.

            try
            {
                con.Open();
                com.ExecuteNonQuery();
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                con.Close();
            }
你这一return ,连接是否能关就是未知之数了 --------------------编程问答-------------------- finally是不管如何都会关的,不用担心
用参数的SQL语句或存储过程,这个倒是搂主应该要注意的问题 --------------------编程问答-------------------- 算三层,跟petshop结构差不多,只是在petshop4里引用的数据工厂 --------------------编程问答-------------------- 上的 --------------------编程问答-------------------- 也在研究学习三层,根据PetShop4.0写了简单的三层....
可以交流互相探讨啊....
msn:  liangyi_neil@hotmail.com --------------------编程问答-------------------- 学了,顶上。

我也初学3层。 --------------------编程问答-------------------- 学习

楼主不错~! --------------------编程问答-------------------- ding --------------------编程问答-------------------- UP --------------------编程问答-------------------- 还不算三层 --------------------编程问答-------------------- 请问代码怎么使用的?我的330605650 加我QQ告诉我啊 谢谢了 --------------------编程问答-------------------- 四:听人说用接口创建对象,我不明白,接口是个契约,里面不都是定义的函数吗,怎么能用接口创建对象呢,拜托给说说

---------------------------
你听说的通过接口创建对象,应该是利用“工厂模式+反射”动态创建对象,这一技术很常使用用,楼主应该掌握 --------------------编程问答-------------------- “工厂模式+反射”动态创建对象并不提昌多用~ --------------------编程问答-------------------- 学无止境啊…… --------------------编程问答-------------------- 嗯,学习了,看来只能在实际的项目中去体会了 --------------------编程问答-------------------- jinglecat老兄真是个热心人啊 --------------------编程问答-------------------- 呵呵,先操作数据,再考虑业务逻辑,后嘛,表示出来,OK。我是这样理解三层的。 --------------------编程问答-------------------- 学习了,谢谢 --------------------编程问答-------------------- 学习哈
顶 --------------------编程问答--------------------
引用 14 楼 amandag 的回复:
1.   不要用字符串拼接语句..用参数

2.

                        try
                        {
                                con.Open();
                                com.ExecuteNonQuery();
                                return   true;
                        }
                        catch
                        {
                                return   false;
                        }
                        finally
                        {
                                con.Close();
                        }
你这一return   ,连接是否能关就是未知之数了


finally是肯定会执行的吧!!! --------------------编程问答-------------------- 感觉还是不错的 有了工厂模式的雏形
加油吧 --------------------编程问答-------------------- web层一般不调用dal层。 --------------------编程问答-------------------- web层一般不调用dal层。 --------------------编程问答-------------------- 学习 --------------------编程问答-------------------- 学习了 --------------------编程问答-------------------- SqlHelper理解有点问题,Helper顾名思义,就是帮助DAL来执行数据库操作的,所以一般都是对ado.net方法的封装,供DAL层调用,在DAL就应该看不到sqlconnection,sqlcommand...一类的对象。sqlhelper内的方法一般都是静态方法,可供dal方便调用。如:

/// <summary>
        /// 执行单条增删改操作
        /// </summary>
        /// <param name="strSQL">增删改语句</param>
        /// <returns></returns>
        public bool ExecuteSQL(string connString, string strSQL)
        {
            bool ReturnResult = false;
            SqlConnection  Conn = new SqlConnection(connString);
            Conn.Open();
            try
            {

                SqlCommand MyCommand = new SqlCommand();
                MyCommand.Connection = Conn;
                MyCommand.CommandText = strSQL;
                MyCommand.ExecuteNonQuery();

                ReturnResult = true;
            }
            catch (Exception Ex)
            {
                ReturnResult = false;
                throw Ex;
            }
            finally
            {
                Conn.Close();
            }
            return ReturnResult;
        }
补充:.NET技术 ,  ASP.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,