The younger brother has recently compiled an O/RM component (of course there are still quite a few functions ).
It should be clear that updating an object to a database must undergo a series of conversions. In particular, the generation of SQL statements is more expensive because there are too many things in the middle.
During the design process, I thought that if an object is inserted into the database, the corresponding Command will be saved in the cache; the next time you perform this operation on the same type of object, check that the cache will be used directly if it is available, which is more efficient.
With this idea, I started to design it (but I still tried it for the first time, after all ).
Because the processing of objects in the cache is complicated, there is a sharing problem in multithreading. If two threads call the same Command at the same time, a processing error will occur!
To better control the sharing of Command objects, a persistent interface is defined for Command objects.
After a period of design and writing, it's a bit fruitful. Just share what you have done.
The following are the test cases of components:
P4 2.4 1G
SqlServer sp3
The Running code is roughly as follows:
Entitys. Customers customer = new Test. Entitys. Customers ();
DateTime dt = DateTime. Now;
Using (HFSoft. Data. IDataSession session = mapcontainer. OpenSession ())
{
Session. Open ();
For (int I = 0; I <2000; I ++)
{
Customer. CustomerID = Guid. NewGuid (). ToString ();
Customer. CompanyName = "henry ";
Session. Save (customer );
}
}
Tp1 = new TimeSpan (DateTime. Now. Ticks-dt. Ticks );
Do not enable cache (five threads run time)
00:00:05. 7031250
00:00:06. 8281250
00:00:05. 0156250
00:00:06. 6875000
00:00:06. 4218750
--------------------------------------------------------
Enable the caching of Five Commands (running time of five threads)
00:00:04. 8906250
00:00:03. 5625000
00:00:02. 8750000
00:00:04. 9375000
00:00:05. 4843750
---------------------------------------------------------
The following is the source code of the cache class:
/// <Summary>
/// Data cache save information asynchronous processing delegate
/// </Summary>
Delegate void EventSaveCache (object key, object value );
/// <Summary>
/// Object cache class
/// </Summary>
Public class Cache
{
Private MappingContainer mContainer;
/// <Summary>
/// Get or set the relational image container of the current cached object
/// </Summary>
Public MappingContainer Container
{
Get
{
Return mContainer;
}
Set
{
MContainer = value;
}
}
/// <Summary>
/// Construct the cache object
/// </Summary>
Public Cache ()
{
//
// TODO: add the constructor logic here
//
}
/// <Summary>
/// Hashtable used to cache data
/// </Summary>
Protected System. Collections. Hashtable _ Cache = new System. Collections. Hashtable ();
Protected Object _ LockObj = new object ();
/// <Summary>
/// Obtain the object of the specified key value
/// </Summary>
/// <Param name = "key"> key value </param>
/// <Returns> object </returns>
Public virtual object GetObject (object key)
{
If (_ Cache. ContainsKey (key ))
Return _ Cache [key];
Return null;
}
/// <Summary>
/// Save the object to the cache based on the specified key value
/// </Summary>
/// <Param name = "key"> key value </param>
/// <Param name = "value"> saved object </param>
Public void SaveCaech (object key, object value)
{
EventSaveCache save = new EventSaveCache (SetCache );
IAsyncResult ar = save. BeginInvoke (key, value, new System. AsyncCallback (Results), null );
}
Private void Results (IAsyncResult ar)
{
EventSaveCache fd = (EventSaveCache) (AsyncResult) ar). AsyncDelegate;
Fd. EndInvoke (ar );
}
/// <Summary>
/// Save the object to the cache based on the specified key value
/// </Summary>
/// <Param name = "key"> key value </param>
/// <Param name = "value"> saved object </param>
Protected virtual void SetCache (object key, object value)
{
Lock (_ LockObj)
{
If (! _ Cache. ContainsKey (key ))
_ Cache. Add (key, value );
}
}
Public int Count
{
Get
{
Return _ Cache. Count;
}
}
/// <Summary>
/// Delete the object with the specified key value in the cache
/// </Summary>
/// <Param name = "key"> key value </param>
Public virtual void DelObject (object key)
{
Lock (_ Cache. SyncRoot)
{
_ Cache. Remove (key );
}
}
/// <Summary>
/// Clear all objects in the cache
/// </Summary>
Public virtual void Clear ()
{
Lock (_ Cache. SyncRoot)
{
_ Cache. Clear ();
}
}
}
/// <Summary>
/// Cache class for a record Operation Command
/// </Summary>
Public class CachePersistentCommand: Cache
{
/// <Summary>
/// Cache record operation commands to the memory
/// </Summary>
/// <Param name = "key"> identifier </param>
/// <Param name = "value"> value </param>
Protected override void SetCache (object key, object value)
{
Lock (_ LockObj)
{
Int count = 0;
If (Container. Config. CommandsCache. ContainsKey (key ))
Count = (int) Container. Config. CommandsCache [key];
System. Collections. IList _ list;
// If the list of such commands already exists in the cache
If (_ Cache. ContainsKey (key ))
{
_ List = (System. Collections. IList) _ Cache [key];
If (count> 0) // The total number of commands cached
{
If (_ list. Count <count) // The cache data volume is less than the total cache data volume.
_ List. Add (value );
}
Else
{
If (_ list. Count <Container. Config. CommandBuffer) // the default list of components whose cache quantity is smaller
_ List. Add (value );
}
}
Else // if the list does not exist
{
If (count> 0 | Container. Config. CommandBuffer> 0) // if the component allows object caching
{
_ List = new System. Collections. ArrayList ();
_ List. Add (value );
_ Cache. Add (key, _ list );
}
}
}
}
/// <Summary>
/// Obtain the relevant command object from the cache
/// </Summary>
/// <Param name = "key"> identifier </param>
/// <Returns> IPersistentCommand </returns>
Public override object GetObject (object key)
{
If (_ Cache. Contains (key) // if the command is cached
{
Foreach (IPersistentCommand cmd in (System. Collections. IList) _ Cache [key])
{
If (! Cmd. State) // whether the command can be locked through the line
If (cmd. Lock () // command Lock
Return cmd;
}
}
Return null;
}
}