Specification for high quality code design patterns and database design for large. NET ERP

Source: Internet
Author: User
Tags foreach generator hash numeric md5 md5 hash numeric value reserved

High-quality code design patterns for large. NET ERP Systems

1 Cached cache

In the system, a large number of cache design patterns are used to cache the data unchanged after the system is logged in, and not read directly from the database. Consuming some memory is much more cost-effective than reading data again from SQL Server. The basic design pattern for caching refers to the following code:

private static concurrentdictionary<string, lookupdialogentity> _cachedlookupdialogentities = new Concurrentdictionary<string, lookupdialogentity> ();
if (!_cachedlookupdialogentities.containskey (key))
Lookupdialog = _cachedlookupdialogentities.getoradd (Key, Lo Okupdialog);
else
_cachedlookupdialogentities[key] = Lookupdialog;



The primary use of the data structure is a dictionary, in which the item in the dictionary is not present, added to it, and then called directly from memory.

Enumerate the places where I can see the application of the cache design pattern in the ERP system, mainly data caching and object caching, resource caching:

1 The text translation in the ERP system is saved in the database table, only once when the system is logged in. Cached in the DataTable.

2) After the system parameters are logged into the system, the current fiscal year, the accounting period, the purchase of a single batch of nuclear process, the length of the material code, whether the number and serial numbers, accounting vouchers before the need for audit, the source of cost accounting (material costs, material costs + labor costs, material costs + labor costs + machine costs), These parameters can be persisted in the entity, the user modifies these parameter values, needs to remind or force the user to exit the login again.

3) System query system can predefined a set of query statements, in the code of the query into the query object, the query object caching, saving SQL statements to query object conversion time. The

4) object instance, when searched in a plug-in way to search for system features included in the assembly, caches the type of program functionality, so the second execution function can be performed fairly quickly. Refer to the example code below to deepen the impression:

Public&nbsp;void&nbsp;openfunctionform (string&nbsp;functioncode) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;functioncode&nbsp;=&nbsp;functioncode.toupper ().
Trim ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type&nbsp;formBaseType&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;if&nbsp; (!_formbasetype.trygetvalue (functioncode,&nbsp;out&nbsp;formbasetype)) &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;assembly&nbsp;assembly&nbsp;=&nbsp;assembly.getexecutingassembly (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp; (type&nbsp; type&nbsp;in&nbsp;assembly. GetTypes ()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbSp;&nbsp;&nbsp;try &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object[]&nbsp;attributes&nbsp;=&nbsp;type.
GetCustomAttributes (typeof (Functioncode), &nbsp;true); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp; (object&nbsp;obj&nbsp;in&nbsp;attributes) &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;functioncode&nbsp;attribute
&nbsp;=&nbsp; (functioncode) obj; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;if&nbsp; (!string. IsNullOrEmpty (attribute. Value) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (!_formbasetype.containskey) (attribute. Value) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;_formbasetype.add (attribute.
Value,&nbsp;type); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (formbasetype&nbsp;==&nbsp;null&nbsp;&amp;&amp;&nbsp; Attribute. Value.equals (functioncode,stringcomparison.invariantcultureignorecase)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formBaseType&nbsp;=&nbsp;type; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;if&nbsp; (formbasetype&nbsp;!=&nbsp;null) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;{&NBSP;&NBSP;&NBSP;&Nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;goto&nbsp;Found;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &NBSP;&NBSP;&NBSP;&NBSP} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;found: &nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; (Formbasetype&nbsp;!=&nbsp;null) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object&nbsp;entryForm&nbsp;=&nbsp;
Activator.CreateInstance (Formbasetype) &nbsp;as&nbsp;Form; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Form&nbsp;
functionform&nbsp;=&nbsp; (Form) entryform; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&Nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;openfunctionform (Functionform); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;}

The



has the complete code for this example in the open source framework of my generic application. The

5) Resource caching system uses a number of resource files that are compiled into an assembly in an embedded manner and, after searching for a resource file, caches the resource in a dictionary (icon, image, text, query statement).

 
2 Query optimizations query Optimize

This is a very easy to understand design pattern, you insist. When we read the data, we read only the least available data and avoid reading unwanted data. With query statements, the following are inefficient query data:

select   *    from company

After the improved statement, changed to read-only data that needs to be used, The improved query is as follows:

select   Companycode, companyname    from company

The latter performance would be much better. For the LLBL Gen Pro I use, turn the above code into program code, which is shown in the following example:

Includefieldslist fieldlist = new Includefieldslist ();
Fieldlist.add (fiscalperiodfields.period);
Fieldlist.add (fiscalperiodfields.fiscalyear);
Fieldlist.add (Fiscalperiodfields.periodno);
Ifiscalperiodmanager Fiscalperiodmanager = clientproxyfactory.createproxyinstance<ifiscalperiodmanager> ();
Fiscalperiodentity fiscalperiodentity = Fiscalperiodmanager.getfiscalperiod (Shared.currentusersessionid, this. Voucherdate, NULL, fieldlist);
This. Period = Fiscalperiodentity.period;
This. FiscalYear = fiscalperiodentity.fiscalyear;
This. Periodno = Fiscalperiodentity.periodno;



Even if you have not contacted Llbl Gen Pro, you can feel the role of type includefieldslist in order to pick the data columns you want to read, that is, what fields to use, what fields to study, and how to avoid reading unwanted fields.

For the above program, its performance cost mainly in reading data and creating objects, in order to performance faster, consider reading data into a DataTable, the readability of the lower but improved performance.

Irelationpredicatebucket&nbsp;&nbsp;filterbucket&nbsp;=&nbsp;new&nbsp;relationpredicatebucket (); FILTERBUCKET.PREDICATEEXPRESSION.ADD (shipmentfields.customerno&nbsp;==&nbsp;this.
Customerno);
FILTERBUCKET.PREDICATEEXPRESSION.ADD (shipmentfields.posted&nbsp;==&nbsp;true); FILTERBUCKET.RELATIONS.ADD (New&nbsp;entityrelation (shipmentdetailfields.orderno,&nbsp;
Salesorderdetailfields.orderno,&nbsp;relationtype.manytomany));
FILTERBUCKET.PREDICATEEXPRESSION.ADD (Shipmentdetailfields.qtyshipped&nbsp;==&nbsp;salesorderdetailfields.qty);
Resultsetfields&nbsp;fields&nbsp;=&nbsp;new&nbsp;resultsetfields (4); Fields.
DefineField (shipmentfields.refno,&nbsp;0); Fields.
DefineField (shipmentfields.payterms,&nbsp;1); Fields.
DefineField (SHIPMENTFIELDS.CCY,&NBSP;2); Fields.
DefineField (shipmentfields.shipmentdate,&nbsp;3); System.data.datatable&nbsp;shipments&nbsp;=&nbsp;userdefinedquerymanager.getqueryresult ( Shared.currentusersessionid,&nbsp;fields,&nbsp;filterbucket,&nbsp;null,&nbsp;null,&nbsp;false,&nbsp;false); 



continue to improve query performance, assuming that the scenario is a sales order table to read the customer number and customer name, we add the Customer Name field directly to the Sales Order table so that each time the sales order is loaded, it can be read directly to the Customer Name field of the Sales Order table itself. Instead of the left connection to the Customer table to read the customer name. The

Entity Framework or Third-party ORM query interfaces should all have the attributes enumerated above.

ORM Queries are not recommended for use with LINQ, and performance is a major consideration. When the ORM framework transforms a query into an entity object, because it is not possible to anticipate which attributes will be used in the next, it is difficult to read all the fields bound to the property, which is the same as the previous select * Read all the fields, delaying the binding properties, and then reading the corresponding database fields when the properties are used. , each with a property to read a database, the database is too frequent connection, and unacceptable.

The following is the most unbearable query I can do, the example in the reference code:

Entitycollection<accountsreceivablejournalentity> Journalcollection = adapter. Fetchentitycollection<accountsreceivablejournalentity> (Filterbucket, 1, sorter, NULL, fieldList);

accountsreceivablejournalentity   lastjournal = journalcollection[journalcollection.count-1];

to fetch the last record in a table, the entire table is read into memory and the last record is taken.

This query can be improved to select top 1 + ORDER BY, and the performance of reading a single piece of data is definitely better than reading an unknown pen data record.

 
3 deferred load Delay load

When using an object, we instantiate the object only if you want to use the object's methods or properties. The code example for design mode is as follows:

paytermentity payterm = null; payTerms.TryGetValue (dataRow[" Payterms "].
ToString (),  out payterm); if  (payterm == null) {    payterm = paytermmanager.getpayterm ( shared.currentusersessionid, datarow["Payterms"].
ToString ());
    payterms.add (Payterm.payterms, payterm); }



Suddenly the idea that this pattern is the implementation of the system cache. To define a private static variable in a type, we use this variable to initialize its instance. Deferred loading avoids the memory and time that it takes to create all the cached objects when the system starts up, and some objects may not be used at all and should not be created.

For example, users log in only to the system, do not make any business document operations, and then exit. If you create a cache of currency or payment terms when you log on, the user does not use the data, which affects system performance.

 
4  Background threads and multithreading backgroundworker/workerthreadbase

. NET provides a back-line program. Solve the problem of long time operation to avoid the main interface card dead. In the system, all involved in database operations, can not be completed in a very short time, are placed in the BackgroundWorker background thread execution. A large number of uses of BackgroundWorker in the system:

1) document additions and deletions check all documents to the insert,delete,update of the data with BackgroundWorker operation.

2) queries all queries about the data to be encapsulated into BackgroundWorker execution.

3 Data Manipulation class features: Data initialization, data restart, accounting for vendor accounts, accounting for customer accounts, data archiving, data backup, data restoration.

4 Business document posting, business document completion, business document cancellation, business document modification.

You cannot use BackgroundWorker when there is no interface, and you can improve performance with multithreaded components. Refer to the following example code:

Private Sealed class Loaditemsworker:workerthreadbase
{
private mrpentity _MRP;
Private concurrentbag<datarow> _itemmasterrows;
protected override void Work ()
{
//long time operation
}


Call the multithreaded component above, see the following example code:

List<loaditemsworker> workers = new list<loaditemsworker> ();
for (int i = 0; i < max_running_thread i++)
{
Loaditemsworker worker = new Loaditemsworker (sessionId, t       his, MRP);
Workers. ADD (worker);
}
Workerthreadbase.startandwaitall (workers. ToArray ());



The multithreaded component Workerthreadbase can find source code and explain articles on Code project.


5 Data dictionary Dictionary

This paper mainly introduces the design pattern of the immutable data dictionary, first look at the data dictionary design of the sex Gender:

Public enum Gender
{
[StringValue ("M")]
[Displayvalue ("Male")]
Male,
[StringValue ( "F")]
[Displayvalue ("Female")]
Female
}


Adds two attributes to the enumeration type, stringvalue for storage, Displayvalue for display in the interface control, which is the same principle as the ValueMember and displaymember of the data source described in data binding. Let's take a look at using code:

Employee employee= ...
Employee. Gender=stringenum<gender>. GetStringValue (Gender.male);

You can also call to get the displayed value Displayvalue:

String Displayvalue=stringenum<gender>. Getdisplayvalue (Gender.male);

This design pattern solves the problem of updating the document in the data dictionary. Writing the source code at the same time designed the document, want to know the value of the data dictionary, directly open the enumeration type definition.


6 Check-execute-Verify Validate-post-verify

Business operations for business logic, compliance with validation-execution-validation design conventions, to see a piece of code to deepen the impression:

try {         adapter. StartTransaction (isolationlevel.readcommitted,  "Postinvoice");                               this.
Validatebeforepost (sessionid, accountsreceivableallocation);          this.
Post (sessionid, accountsreceivableallocation);          this.
Verifygeneratedvoucher (sessionid, accountsreceivableallocation);                    
       adapter.commit (); catch {          adapter.
Rollback ();
          throw; }

The


verifies the data that you want to perform, then the data is manipulated, and the expected data is validated after the operation completes.

such as invoice generation vouchers, first verify that the amount on the invoice is greater than 0, whether the invoicing time is a business logic such as the current period, and then perform the voucher generation (voucher) action, and finally verify that the borrower of the generated voucher is consistent, and whether the debit side inconsistencies caused by the decimal point are considered, Whether the generated voucher amount is equal to the amount on the original invoice.

 
7 Pre-execute-execute-onbefore-perform-onafter

Sixth explains the business Accounting method, The seventh article here is the common framework and application interaction methods. Inherited. NET form or derived class to change the behavior of a base class, you need to design a method to do this. First look at a piece of code familiar with this design pattern:

cancelablerecordeventargs e = new  Cancelablerecordeventargs (this.
currententity); This.
Onbeforecanceledit (e); if  (This._beforecanceledit != null)      this._beforecanceledit (This,
&NBSP;E);
if  (E.cancel)       return false; Bool flag = this. Doperformcanceledit (this.
currententity);   Recordeventargs args2 = new recordeventargs (this.
currententity); This.
Onaftercanceledit (ARGS2); if  (This._aftercanceledit != null)      this._aftercanceledit (This, &NBSP;ARGS2); 



to deepen understanding of this design pattern, I split the above code snippet into three sections with two lines of space, which are explained in detail in these three sections:

Onbefore The derived class can set parameters into the base class to affect the behavior of the base class before performing the operation. For example, you can execute an event, or you can pass the cancellation condition to the base class, and the derived class passes the CANCEL=TRUE flag bit to the base class, completely canceling the current operation. This is a design way for derived classes to affect the behavior of a base class. Another method is to throw an exception, which causes the entire stack to roll back. The

perform performs the action you want to do, and this name follows. NET's specification. For example, we want to directly execute the button in the code click event, you can write the method of calling the code: Btnok.performclick (); The

Onafter after execution completes. You can override the results of execution, or you can call an event in a derived class. The

 
8 metadata Metadata

Framework completes a number of applications that can be invoked in one sentence, with the most credit for metadata. Each field of an entity object in the system has an attached property sheet, which is referenced by the following code definition:

Private&nbsp;static&nbsp;void&nbsp;setupcustompropertyhashtables () {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;_customProperties&nbsp;=&nbsp;new&nbsp;Dictionary&lt;string,&nbsp;string&gt; (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_fieldscustomproperties&nbsp;=&nbsp;new&nbsp;dictionary
&lt;string,&nbsp;Dictionary&lt;string,&nbsp;string&gt;&gt; (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_customproperties.add ("SupportDocumentApproval", &nbsp;@)
"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_customproperties.add ("SupportExternalAttachment",
&nbsp;@ ""); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&lt;string,&nbsp;string&gt;&nbsp;
fieldhashtable; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fieldhashtable&nbsp;=&nbsp;new&nbsp;dictionary&lt;string
,&nbsp;string&gt; (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_fieldscustomproperties.add ("Recnum",&nbsp;
fieldhashtable); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nBsp;&nbsp;&nbsp;&nbsp;fieldhashtable&nbsp;=&nbsp;new&nbsp;dictionary&lt;string,&nbsp;string&gt; ();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fieldhashtable.add ("Alloweditfornewonly", &nbsp;@ "");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fieldhashtable.add ("CapsLock", &nbsp;@ ""); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_fieldscustomproperties.add ("RefNo", &nbsp;fieldHashtable
); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fieldhashtable&nbsp;=&nbsp;new&nbsp;dictionary&lt;string
,&nbsp;string&gt; (); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fieldhashtable.add ("ReadOnly", &nbsp;@ "");


Seeing the code above, each property of the current entity can be bound to a Dictionary object, which is done with a code generator. So play the imagination, put the special properties of the field into the attached properties of the entity properties, and the framework can accomplish many of the basic functions. The

sees the addition of alloweditfornewonly and CapsLock two metadata in the Refno property above. In the System Framework section, the code references are as follows:

Dictionary&lt;string,&nbsp;string&gt;&nbsp;fieldscustomproperties&nbsp;=&nbsp;getfieldscustomproperties (
Boundentity,&nbsp;bindingmemberinfo.bindingfield); if&nbsp; (fieldscustomproperties&nbsp;!=&nbsp;null) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp; ( Fieldscustomproperties.containskey ("CapsLock")) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;base.
charactercasing&nbsp;=&nbsp;charactercasing.upper; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if &nbsp; (!) ( This. alwaysreadonly&nbsp;| | &nbsp;!fieldscustomproperties.containskey ("Alloweditfornewonly")) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;this._allowEditForNewOnly&nbsp;=&nbsp;true; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}










Metadata is done through the entity design of the code generator, the framework gets the metadata of the entity code, makes the common settings on the control properties, and saves a lot of duplicate code. The above is the metadata on the attribute, also can increase the metadata on the entity level, the existence of metadata has brought convenience to the frame design.





If you are designing an ORM framework that allows you to add metadata (custom attributes) to the attributes of entities and entities, it can be a great convenience for the scalability of your system.











Analysis of 20 database design specifications for large. NET ERP system





When the system becomes larger, the designer of the database is strictly controlled, and a specification book is provided for the implementation of the reference. In the procedural framework, there is also a mandatory agreement when non-compliance with the norm times error.





The following 20 terms are a design agreement that I extracted from a large ERP system with more than 1000 database tables for reference.








1 The first field in all tables is the record number recnum, for data maintenance





[Recnum] [Decimal] (8, 0) Not NULL IDENTITY (1, 1)





In the case of data maintenance, we can write this directly:





UPDATE company SET code= ' FLEX ' WHERE recnum=23





2 Add 4 prerequisite fields per table, used to record the creation time of the pen data, the creator, the last modified person, the last modified time





[CreatedDate] [DateTime] Null


[CreatedBy] [nvarchar] (a) COLLATE sql_latin1_general_cp1_ci_as NULL,


[Reviseddate] [DateTime] Null


[Revisedby] [nvarchar] (a) COLLATE sql_latin1_general_cp1_ci_as NULL





These fields are forced to be read in the framework program, and the default write value.








main foreign key design of 3 master-slave table





The primary table uses the reference number REFNO as the primary key, and the Refno,entryno as the primary key from the table. REFNO is a string type that can be used in the document encoding function to automatically fill in the document flow number, from the table Entryno is the line number, Lineno is the keyword of SQL Server, so use Entryno as the line number.





In the case of a three-tier table, the primary key of the third-tier table is Refno,entryno,detailentryno, and the third primary key is used to automatically grow line numbers.








4 design Document Status field


Field meaning


Posted posted, confirmed


Closed is complete


Cancelled has been canceled


Approved has been approved


Issued has been sent to the material


Finished is complete


Suspended has been canceled





5 fields have similar meanings, and the same words are prefixed.





For example, in the work list of cost accounting, labor costs, machine costs, energy costs, expressed in English as Laborcost,machinecost,energycost





But in order to facilitate the regulation group, we put the cost to the front of the field, so the above three fields named Costlabor,costmachine,costenergy.





Readability the latter is better than the former, Visual studio or SQL prompt IntelliSense can also help increase the accuracy of field input.








6 Document Reference key name Sourcerefno Sourceentryno





Sales shipping shipment will refer to which sales document is sent, you can add the following reference key Sourcerefno,sourceentryno to represent the reference number and line number of the sales order reference. Fields at the beginning of source are typically used for document reference associations.





7 data Dictionary key design





For example, the employee's main document interface's employee gender gender, my approach is to use enumeration definitions in source code. The gender enumeration is defined as follows:





public enum Gender


{


[StringValue ("M")]


[DisplayText ("Male")]


Male,





[StringValue ("F")]


[DisplayText ("Female")]


Female


}





A common method of calling enumerations in code, reading the enumeration's stringvalue to the database, and reading the enumeration's displaytext is displayed in the interface.





After this layer of design, the database on the design of the dictionary has been standardized, to avoid the data dictionary of the increase or decrease in the number of items to the system caused by the problem.








8 Numeric Type field length design





Price/qty Quantity/Unit price 6 decimal places nnnnnnnnnn.nnnnnn format (10.6)


Amount Amount 2 decimal places nnnnnnnnnnnn.nn format (12.2)


Total AMT amount 2 decimal nnnnnnnnnnnnnn.nn format (14.2)





The reference number defaults to 16 characters in length, increases to 30 characters when not enough, and then increases to 60 characters. This ensures that the first reference number input control for each document will look the same length.





Unless specifically required, in general, the length of the control in the interface is taken from the defined length of the field in the mapped database.








9 Add 10 custom fields to each document header and detail, the base table adds 20 custom fields





Refer to the custom field for the vendor master, and the name of the custom field is unified with Userdefinedfield.





ALTER TABLE Vendor ADD COLUMN [user_defined_field_1] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_2] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_3] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_4] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_5] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_6] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_7] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_8] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_9] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_10] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_11] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [User_defined_field_12] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_13] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_14] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_15] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_16] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_17] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_18] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_19] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL


ALTER TABLE Vendor ADD COLUMN [user_defined_field_20] nvarchar (MB) COLLATE sql_latin1_general_cp1_ci_as NULL








design of conversion fields for more than 10 currency (standard currency)





The amount or unit price defaults to the currency in the journal, and the value of the base currency is also recorded when the default currency is not the same as the standard currency.





Sales order Sales Amount SalesAmount or Salesamt, and the standard currency field is defined as salesamountlocal or salesamtlocal





It is usually the value of the local currency that is appended to the original field.








11 Design of various date fields


Field name meaning


Trandate Date Billing Date Tran is a shorthand for transaction


Posteddate Posting Date


Closeddate finish Date


Invoicedate Development Ticket Date


DueDate Due Date


Scheduledate Schedule date, this field is different for different document meanings. For example, the sales only refers to the delivery date, and the purchase order refers to the receipt date.


OrderDate Order Date


PayDate Payment Date


CreatedDate Date Created


Reviseddate Modification Date


Settledate Payment Date


IssueDate Date of issue


Receiptdate date of receipt of goods


ExpireDate Expiration Time








12 Financial-related documents containing three standard fields





FiscalYear fiscal year, Periodno accounting period, Period the previous two combinations. Take the foreign fiscal year as an example, FiscalYear is 2015,periodno is the 4,period is 2015/04.





Europe and the United States accounting period is starting from April each year, it is necessary to pay attention to the accounting period and time does not necessarily link, see the accounting period is 2015/04, not necessarily 2015 of the April, it is only said that this is the fourth period of 2015 fiscal year, specific in which time period to see the definition of








13 Document automatic generation Directentry





Some documents are generated by other documents and should not be logically supported by editing. For example, sales delivery shipment will produce a warehouse order, out of the warehouse list should not support editing, can only do the post deduction inventory operation. This requires Directentry standard fields. When manually creating an out of order, set Directentry to True to indicate the value of the field in the editable document, and set the Directentry to False if the delivery form generated by another document pass is created, which means that the document cannot be edited. This situation also occurs in the function of the business document Generation Accounting voucher (voucher), and if you can modify fields such as the quantity amount passed by the original document, it will cause a mismatch with the source list, causing the system to account for problems.






Design of 1400-point ratio field






Percentage percent value, used for discount rate, loss rate and other related ratios set up place. It is recommended to use a numeric type, which is represented by a script





[Scraprate] [Decimal] (5, 2) Null








Two decimal digits are reserved, and the integer part supports 1-999 three digits. Often the whole number of parts 2 can be, with 3-bit is also to support a number of special industries (material loss rate of more than 100) requirements.








15th log record number Logno field design





The design of the Logno field is somewhat ingenious, with the example of a warehouse list, a sheet has 5 lines of material details, each line of material out of the warehouse will be deducted inventory, and then write the material in and out of the journal, because the five elements of the material out of the warehouse from the same warehouse list, so that the five elements of the item's journal Logno are set to the same value. When querying for data, you can see which items are out at the same point in time by grouping this field, which is very important for quick query.








16 base table add Name, name long write, substitution name three fields





For example, the Supplier Vendor table, add the following three fields:





Description supplier name, such as Microsoft Company.





Extdescription supplier name is long written, such as the electrical industry's southern network is the full name of the Southern National Grid Limited.





Altdescription the name of the vendor name, used in a report or other document reference. For example, the supplier in the purchase order is controlled by Microsoft, or by Microsoft with the substitution name, by the parameter (whether by proxy name).








17 File class table add MD5 hash field





For example, the product data management system to read drawings, document features added to the attachment file, which involves the file read and write references, consider the MD5 hash value of the file. The MD5 of the file is equivalent to the unique identity of the file, when downloading files on the Internet, the website often releases the MD5 value of the file to facilitate comparison and check. When the MD5 value of a file downloaded to this computer is inconsistent with the value given on the site, it is possible that the file has been modified by a Third-party program and cannot be trusted.








18 The primary key for the datasheet is a string instead of a number





For example, the Currency field in the sales list is the currency string value of the currency RMB/HKD/USD, or the numeric key that holds the Currency table, 1/2/3.





Storing the former is relatively easy for report making, but it is relatively cumbersome to modify. Storing the latter is easy to modify data, but you need to add a left and right connection to the report class or query class to see the currency represented by the number. Kingdee uses the latter, and its BOS system does not allow direct correlation between the data tables, but indirectly associates the table with the ID value.





In the system I see, only one fiscal period feature (fiscal year fiscal years) uses a numeric value as the primary key, and the rest of the document is a string master key.








19 using the customary shorthand





Modular module Shorthand


Abbreviation Full Name


SL Sales


PU Purchasing Procurement


IC Inventory Warehouse


AR Account Receivable Receivable


AP Account payable Handle


GL General Ledger Ledger


PR Production Production





Name Shorthand


Abbreviation Full Name


Uom Unit of Measure


Ccy Currency Currency


AMT Amount Amount


Number of Qty Quantity


Qty per Quantity per dosage


STD output Standard output standard output


ETA estimated time of arrival scheduled arrival times


ETD estimated time of departure scheduled departure


COD Cash on Delivery c.o.d.


So sales orders


PO Purchase Order Purchase List








20 Inventory Document quantity status





Qty on Hand in hand volume





Qty Available Usable Amount





Qty on Inspect in the number of tests





Qty on commited committed quantity





Qty Reserved Reserved Quantity





Each of the above fields have the meaning of standards and industry conventions, can not be arbitrarily modified to take a number of methods.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.