The system adopts the | B / S structure, a total of three layers, respectively, the data access layer, the business rule layer, and the web appearance layer. They have their own responsibilities, each for the political integral function system, and the roof of the data access layer is responsible for the access to the data source (here the data source refers to SQL Server 2000), the business rule layer is responsible It is the processing of the data according to the business process, and the web appearance layer is responsible for providing an interface to the user, only responsible for inputting output data. This design is very common, it provides a better maintenance system.
design:
1) Data Access Layer:
Many people are willing to package a large number of SQL scripts in this layer to simplify the upper layer design, but such a design is not suitable! If the business is generally changed, if the SQL script "hardcodes" together, the source code for the program has to be modified. And the user is usually only packaged binary! So better approach is to put the script of the operation of the data outside, usually put it close to the data, such as SQL Server, here we put it
Writing into a storage procedure on the SQL Server server. Two benefits have been written as a storage process: First, when the business changes, as long as the memory is changed. Second, there is no need to transfer a large number of scripts to the database server parsing execution, bringing a lot burden to the network. But just call a stored procedure name, greatly reduces the burden on the network burden and the intermediate layer. Such as: performing the operation of adding users
Create Procedure dbo.user_create
@RealName VARCHAR (50),
@Deptname varchar (50),
@Hashedpassword varchar (50),
@Tel Varchar (50),
@Address varchar (50),
@DutyName VARCHAR (50),
@Username varchar (50)
AS
Begin TRAN
INSERT INTO [User] (Username, RealName, DePtname, Hashedpassword, Tel, Address, DutyName) Values (@ username, @ realname, @ deptname, @ haShedpassword, @ tel, @ address, @ DutyName)
IF @@ error! = 0
Begin
Rollback
Return 0
end
Else
Begin
Commit
Return 1
end
For methods of performing stored procedures and maintenance and database connection status (such as: ExecSql (String SQL), open ()) should be encapsulated in a public class, and not every class has its own database method! Such intentions can reduce duplicate dependencies, and if this shared class method is abstract to become an interface, let all this interface used to use this interface, use it when the shared class changes, does not know these changes Reduce dependencies mean better adaptation!
Such as:
Public Class Database: IDisposable, isqldatabase (reference to codeplus)
{
Private SqlConnection CON;
PRIVATE DBCONFIG M_CONFIG = dbconfig.instance;
Public int Runproc (String Procname)
{
SQLCommand cmd = createcommand (procname, null); cmd.executenonquery ();
THIS.CLOSE ();
Return (int) cmd.parameters ["ReturnValue"]. Value;
}
Public int Runproc (String Procname, Sqlparameter [] PRAMS)
{
SQLCommand cmd = createcommand (procname, prams);
cmd.executenonquery ();
THIS.CLOSE ();
Return (int) cmd.parameters ["ReturnValue"]. Value;
} .......
}
interface:
Public interface isqldatabase
{
Int runproc (String Procname);
INT Runproc (String Procname, Sqlparameter [] PRAMS);
Void RunProc (String Procname, Out SqlDataReader DataRead);
Void Runcommand (String Command, Out SqlDataReader DataRead);
Void Runproc (String Procname, Sqlparameter [] PRAMS, OUT SQLDATAREADER DATAREADER;
SQLCommand CreateCommand (String Procname, SqlParameter [] PRAMS;
Void open ();
Void close ();
SQLParameter makeinparam (String paramname, sqldbtype dbtype, int size, object value);
SQLParameter makeoutparam (String paramname, sqldbtype dbtype, int size);
SQLParameter makeparam (String paramname, sqldbtype dbtype, int32 size, parameterdirection direction, object value);
}
For connection information, if the connection string should not appear in all places where the database is used, it is responsible for adjusting all of the classes when deploying! So it is wise in the XML configuration file (divided into integration and hybrid security), and use a class to manage it.
The content of the XML file:
XML Version = "1.0" Standalone = "YES"?>
Dbconfig>
Dbconfig>
NewDataSet>.
For the data entity layer, it is responsible for transmitting data, which is where the data is exchanged. Several factors should be considered when designing:
First: Performance, the place where exchange data must be exchanged fast, accounting for less memory.
Second: The business rules can use them effectively.
Third: It is conducive to the interface part, that is, can be used with the user control to help simplify the development of the interface.
In order to meet the first requirements, the value domain of the entity can be shifted in the base class, so that two classes are inheritance relationships and each negative. The number of instances of base classes (numeric class) is not proportional to its subclass (method class) instance, and the number of base class instance is always greater than the number of method instances. It is generally N: 1, which eliminates no necessary memory spending, which greatly improved performance. For some method parameters list, you can use the base class object instead.
Method class integrates a commonly used data processing method, once the business rule class uses it, can greatly simplify the complexity of the rules class, and the designer can concentrate on design rules and do not have to consider the problem of physical classes. Due to the value domain shift, put the value domain into properties, the control on the interface will be binding to these attributes. (.NET control characteristics)
Entity class:
(Value class)
Public Class logrow: MarshalByrefObject, iComparable
{
Protected string m_operatetype;
Public Virtual String OperateType
{
Get {return m_operatetype;
Set {m_operatetype = value;
}
........
Public logrow ()
{// TODO: Add constructor logic here
}
#Region iComparable member
Public int compareto (Object obj)
{
Logrow rotow = (logrow) obj;
IF (rotater.equals (this.operator) && rotory (this.operateType) && rowRateTime.Equals (this.operatetime) && row.contents.equals (this.contents))
Return 1;
Return 0;
}
#ndregion
}
Method Category:
Public Class log: logrow
{
Public log ()
{
}
Public Bool Create (String OperationTYPE, String Contents, String Operator, System.Datetime Operatetime)
{
Database data = new database ();
Sqlparameter [] PRAMS = {
Data.makeinparam ("@ OperateType", System.Data.sqldbtype.varchar, 50, operatetype,
Data.makeinparam ("@ contents", system.data.sqldbtype.varchar, 255, contents,
Data.makeinparam ("@ operator", system.data.sqldbtype.varchar, 50, operator),
Data.makeinParam ("@ Operatetime", System.Data.sqldbtype.Datetime, 8, operatetime)}
INT Reval = Data.Runproc ("log_create", prams);
Data.Close ();
Data.Dispose ();
IF (Reval == 1)
{
Return True;
}
Else
{
Return False;
}
}
Public Bool Create (Logrow LogObject)
{
Return this.create (logObject.operatetype, logObject.contents, logObject.operator, logobject.operatetime);
}
Public Bool Delete (System.Datetime OperateTime)
{
Database data = new database ();
Sqlparameter [] PRAMS = {
Data.makeinparam ("@ Operatetime", System.Data.sqldbtype.Datetime, 8, OperateTime)
}
INT Reval = Data.Runproc ("log_delete", prams);
Data.Close ();
Data.Dispose ();
IF (Reval == 1)
{
Return True;
}
Else
{
Return False;
}
}
.......
}
2) Business return layers:
There must be its own independent custom anomalous class, and for business methods to properly use multi-threaded improvement performance. It is best to use the TeampleTemotHED mode integration process and adapt to future business changes or set the method to Virtual!
Public Class Ommanager
{
PRIVATE User;
Private userrole Userrole;
PRIVATE ROLE ROLE;
Private rolepopedom rolepopedom
PRIVATE STRING M_CURRENTUSERNAME;
PRIVATE STRING M_CURRENTPASSWORD;
Public OMManager (String Currentusername, String CurrentuserencryptedPassword)
{
User = new user ();
Userrole = new userrole ();
Role = new role ();
RolePopedom = new rolepopedom ();
IF (NEW SecurityValidate ()). Validator (CurrentuserName, CurrentUserencryptedPassword)
{
THIS.M_CURRENTUSERNAME = CURRENTUSERNAME;
THIS.M_CURRENTPASSWORD = CURRENTUSERENCRYPTEDPASSWORD;
}
Else
{
Throw New SecurityException ("Invalid User Name / Password");
}
}
Public Virtual String NewUser (UserRow NewUserData, String [] AssignedRoles)
{
String m_haashedpassword = stringencryptor.encryptor (newuserdata.hashedpassword);
NEWUSERDATA.haShedPassword = m_haashedpassword; if (user.create (newuserdata) && userrole.create (newuserData.user, assignedroles))
{// Todosomething}
Return NULL;
}
........}
3) Web interface layer: To perform business functions using rule layers, but not all through rule layers, but data requires business processing, reference rule layers, if the service does not need to be handled (eg, fill one The drop-down list can directly use the data access layer, which can reduce unnecessary performance expenses. For security, you must use the rule class must be verified. For performance, you can use ASP.NET cache technology to solve