类似于在TransactionScope范围内建立的数据库连接的行为方式,我希望能够在我的类中测试它是否在另一个类的实例中?
我的情景
我有一个构建所有数据库对象的类(EntityBase),并且具有AddToDatabase,UpdateInDatabase,DeleteFromDatabase等方法。
我想创建一个BulkLoader类,它将以批量方式处理插入。这将有一个完整的方法,如TransactionScope类,这将是数据加载到数据库的点。
这将需要更改EntityBase类,以便在BulkLoader类的范围内进行实例化并与该类进行交互时,它的行为会有所不同。
示例代码:
using (BulkLoader bulk = new BulkLoader(connection, transaction))
{
foreach (IToDatabase assignment in assignmentsCollection)
{
assignment.WriteToDataBase(connection, transaction);
}
bulk.Complete();
}
class ClientAssignment : IToDatabase
{
public int WriteToDataBase(IDbConnection connection,
IDbTransaction transaction)
{
foreach (EntityBase account in accountsCollection)
{
account.AddToDataBase(connection, transaction);
}
foreach (EntityBase person in personsCollection)
{
person.AddToDataBase(connection, transaction);
}
}
}
class EntityBase
{
public virtual int AddToDatabase(IDbConnection connection,
IDbTransaction transaction)
{
// question relates to this bit
if (inBulkLoaderClass)
{
// interact with bulk loader
}
else
{
// do existing code
}
}
}
答案 0 :(得分:4)
您可以使用ThreadStaticAttribute:
public class BulkLoader : IDisposable
{
[ThreadStatic]
private static BulkLoader currentBulkLoader;
public BulkLoader()
{
if (InBulkLoader)
{
throw new InvalidOperationException();
}
currentBulkLoader = this;
}
public void Dispose()
{
currentBulkLoader = null;
}
public static bool InBulkLoader
{
get { return currentBulkLoader != null; }
}
public static BulkLoader CurrentBulkLoader
{
get { return currentBulkLoader; }
}
}
我一般不热衷于线程静态,但我认为在这种情况下可能没问题。检查构造函数确保您永远不会处于“嵌套”批量加载器中。如果希望能够嵌套它们,请保留一个计数器(在构造函数中递增,在Dispose调用中递减)。
答案 1 :(得分:1)
嗯,你可以用环境对象(特别是线程静态字段)做一些事情,但它并不漂亮。我认为如果逻辑不同,它首先应该是一个单独的方法。另外,请注意,一个观点是实体对象无论如何都不会与数据库交谈 - 他们的工作是表示对象的状态;存储库类(或类似的)的工作是担心持久性。然后你的存储库将有两个策略来处理事情。也许有一个IBokRepository接口,repo可以(可选)实现,等等。
答案 2 :(得分:0)
我同意Marc的观点。我们也采用与Marc几乎相同的方法。我想这是解决这个问题的标准和最佳方式。虽然我对这里的线程静态业务并不熟悉,但是不能在这方面提出更多建议。