如何检查当前操作是否在对象范围内?

时间:2009-02-25 09:25:30

标签: c# .net-2.0

类似于在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
        }
    }
}

3 个答案:

答案 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几乎相同的方法。我想这是解决这个问题的标准和最佳方式。虽然我对这里的线程静态业务并不熟悉,但是不能在这方面提出更多建议。