XRepository
所属分类:云数据库/云存储
开发工具:C#
文件大小:539KB
下载次数:0
上传日期:2010-09-19 19:36:10
上 传 者:
sh-1993
说明: 位于System.data之上的数据层,用于简化以存储库为中心的代码优先的项目开发...
(A data layer that sits on top of System.Data to streamline project development where repository-focussed code is preferred over ORM techniques. Additionally, XRepository provides a solution for simplifying transactional operations when mixing and matching different methods inside arbitrary transactional blocks without those methods being)
文件列表:
License.txt (1474, 2010-09-20)
XRepository.Sample (0, 2010-09-20)
XRepository.Sample\Program.cs (405, 2010-09-20)
XRepository.Sample\Properties (0, 2010-09-20)
XRepository.Sample\Properties\AssemblyInfo.cs (1430, 2010-09-20)
XRepository.Sample\System.Data.SQLite.DLL (1102336, 2010-09-20)
XRepository.Sample\XRepository.Sample.csproj (2730, 2010-09-20)
XRepository.Tests (0, 2010-09-20)
XRepository.Tests\App.config (677, 2010-09-20)
XRepository.Tests\FakeDb.cs (29865, 2010-09-20)
XRepository.Tests\Local.testsettings (418, 2010-09-20)
XRepository.Tests\Properties (0, 2010-09-20)
XRepository.Tests\Properties\AssemblyInfo.cs (1388, 2010-09-20)
XRepository.Tests\StorageOperationTests.cs (1466, 2010-09-20)
XRepository.Tests\TraceAndTestImpact.testsettings (398, 2010-09-20)
XRepository.Tests\XRepository.Tests.csproj (3101, 2010-09-20)
XRepository.Tests\XRepository.vsmdi (510, 2010-09-20)
XRepository.sln (4455, 2010-09-20)
XRepository (0, 2010-09-20)
XRepository\AtomicStorageOperation.cs (562, 2010-09-20)
XRepository\ConnectionSource.cs (4479, 2010-09-20)
XRepository\ConnectionStateManager.cs (5765, 2010-09-20)
XRepository\Data (0, 2010-09-20)
XRepository\Data\StorageOperationExtensions.cs (81, 2010-09-20)
XRepository\OperationContext.cs (1157, 2010-09-20)
XRepository\Properties (0, 2010-09-20)
XRepository\Properties\AssemblyInfo.cs (1467, 2010-09-20)
XRepository\StorageOperation.cs (1684, 2010-09-20)
XRepository\XRepository.csproj (2652, 2010-09-20)
XRepository
===========
XRepository is a data abstraction layer designed to simplify the process of managing connections and transactions
within any execution context, irrespective of the depth of nested methods participating in an operation and without
forcing any of those methods to need connection or transaction objects passed to them, or for them to assume that they
are participating in the context of a greater storage operation. Using XRepository, all methods that perform database
operations can be built in a way that allows them to act independently and without knowledge of whether their calling
methods have called them in the scope of another database operation, but still allow them to automatically participate
in those operations, transactional or not, if present.
XRepository is built with a code-first, convention-over-configuration approach. You can configure as much or as little
as you like, but "out of the box", you should be able to have your project's data layer up and running extremely
quickly with very few lines of code.
The two classes you will use are `StorageOperation` and `AtomicStorageOperation`. Both should be initialised with
`using` blocks to guarantee that when they are no longer required, they are disposed of immediately. Disposal allows
the storage operation to complete, closing connections, committing transactions, etc.
StorageOperation
----------------
`StorageOperation` represents an shared connection in the current execution context. A nested set of method calls can
each construct and dispose their `StorageContext` objects and each instance will automatically know whether it is part
of a greater storage operation (and thus subscribe to that operation) or whether it has been created independently and
thus should itself manage connection and disconnection from a given source. The `Connection` object is automatically
opened as soon as it is accessed the first time and closed when the initiating `StorageContext` object disposes.
`StorageOperation` should not be passed or referenced outside of the thread in which it was created. New instances of
`StorageOperation` automatically operate within the context of the current thread, which means if a secondary thread
starts a new storage operation while a second storage operation is in progress on a different thread, it will create
and manage its own connection, preventing multiple threads from interfering with each other. Thus, XRepository is
thread safe as long any given `StorageOperation` object is referenced only from within the scope and thread in which it
was created.
In summary, do not pass references to a `StorageOperation` object outside of the scope in which it was created. Nested
method calls should each construct and dispose their own `StorageOperation` object, and in doing so, XRepository will
automatically manage subscription and unsubscription of any execution context to a given connection. Also, unless you
have a very good reason for doing so, ALWAYS use `using` blocks to construct and dispose of `StorageOperation` objects.
AtomicStorageOperation
----------------------
`AtomicStorageOperation` inherits from `StorageOperation` and thus follows all of the same rules that govern the
base class. However, operations performed within the context of an `AtomicStorageOperation` instance are transactional.
To signal a successful atomic operation, call the `Complete()` method of the `AtomicStorageOperation` object in the
current scope and context. Just as with `StorageOperation`, if a given atomic operation is performed from a method that
is nested within the context of another `AtomicStorageOperation` object at a shallower level in the stack, then the
initiating `AtomicStorageOperation` instance will govern the final commit or rollback for the operation. if
`Complete()` is not called within any single `AtomicStorageOperation` instance participating in the current execution
context, then the initiating `AtomicStorageOperation` instance will cause all operations performed in that context to
roll back upon its disposal, including nested operations that are only being performed within a regular
`StorageOperation1` instance.
You can specify a particular `IsolationLevel` for an atomic operation, but it will be only be used if the
`AtomicStorageOperation` instance is the initiating instance within the current execution context. If the operation is
nested inside another atomic operation, the isolation level used will be that of the `AtomicStorageOperation` instance
that initiated the transaction.
Examples
--------
### Simple usage outside of repository to ensure contained method calls use the same connection
using(new StorageOperation())
{
// work performed here ensures that calls to your repositories will all use the same connection
}
### Usage inside of repository to obtain and use a connection
using(var op = new StorageOperation())
{
// retaining a reference to the StorageOperation allows your repository to access the current Connection object
var command = op.Connection.CreateCommand();
// do work...
}
### Using a storage operation to bring multiple methods calls into the same connection context
public void IndependentMethod1()
{
using(new StorageOperation())
{
// do work here
}
}
public void IndependentMethod2()
{
using(new StorageOperation())
{
// do work here
}
}
public void PerformBulkOperation()
{
using(new StorageOperation())
{
IndependentMethod1();
IndependentMethod2();
}
}
### Perform an atomic operation
using(var op = new AtomicStorageOperation())
{
// do work, then if successful...
if(successful)
op.Complete();
}
### Perform an atomic operation using a specific `IsolationLevel`
using(var op = new AtomicStorageOperation(IsolationLevel.ReadUncommitted))
{
// do work, then if successful...
if(successful)
op.Complete();
}
### Perform a bulk operation, with multiple methods participating in the same transaction
public void IndependentMethod1()
{
using(var op = new AtomicStorageOperation())
{
// do work here
if(successful)
op.Complete();
}
}
public void IndependentMethod2()
{
using(new StorageOperation())
{
// do work here
}
}
public void PerformBulkOperation()
{
using(var op = new AtomicStorageOperation())
{
IndependentMethod1();
IndependentMethod2();
// if the call to IndependentMethod1 failed and op.Complete() was not called, then the transaction will
// roll back, even though we are calling Complete() here.
op.Complete();
}
}
### Perform a bulk operation, with only some parts of the operation participating in a transaction
public void IndependentMethod1()
{
using(var op = new AtomicStorageOperation())
{
// do work here
if(successful)
op.Complete();
}
}
public void IndependentMethod2()
{
using(var op = new AtomicStorageOperation())
{
// do work here
if(successful)
op.Complete();
}
}
public void IndependentMethod3()
{
using(new StorageOperation())
{
// do work here
}
}
public void PerformBulkOperation()
{
using(new StorageOperation())
{
// this call will complete irrespective of what comes after it, as there is no active atomic context
IndependentMethod3();
using(var op = new AtomicStorageOperation())
{
IndependentMethod1();
IndependentMethod2();
// if either method fails to call Complete(), then the transaction will roll back when this using
// block exits and thus disposes
op.Complete();
}
// this call will complete irrespective of the previous atomic transaction's success
IndependentMethod3();
}
}
近期下载者:
相关文件:
收藏者: