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

发布于 2024-07-14 02:41:49 字数 1422 浏览 4 评论 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
        }
    }
}

Similar to how database connections made within the scope of a TransactionScope will behave accordingly, I want to be able to test inside my class whether it is within an instance of another class?

My Scenario

I have a class (EntityBase) that all database objects are built upon, and has methods such as AddToDatabase, UpdateInDatabase, DeleteFromDatabase.

I want to create a BulkLoader class, that will handle inserts in a bulk fashion. This will then have a complete method, like the TransactionScope class, which will be the point that the data is loaded to the database.

This will require changing the EntityBase class so that it behaves differently if it is being instanitated within the scope of a BulkLoader class, and interacting with that class.

Example code:

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
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

天冷不及心凉 2024-07-21 02:41:50

您可以使用 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 调用中递减)。

You could use 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; }
    }
}

I'm not generally keen on thread statics, but I think it's probably okay in this case. The check in the constructor makes sure you'll never be in a "nested" bulk loader. If you want to be able to nest them, keep a counter instead (increment in the constructor, decrement in the Dispose call).

红墙和绿瓦 2024-07-21 02:41:50

好吧,您可以对环境对象(特别是线程静态字段)做一些事情,但这并不漂亮。 我认为如果逻辑不同,它首先应该是一个单独的方法。 另外,请注意,一种观点是实体对象无论如何都不应该与数据库对话——它们的工作是表示对象的状态; 存储库类(或类似类)的工作就是担心持久性。 那么你的存储库将有两种策略来应对事情。 也许存储库可以(可选)实现一个 IBulkRepository 接口,等等。

Well, there are some things you can do with ambient objects (in particular thread-static fields), but it isn't pretty. I'd argue that if the logic is different, it should be a separate method in the first place. Also, note that one point of view is that entity objects shoudn't be talking to the database anyway - their job is to represent the state of an object; it is the job of a repository class (or similar) to worry about persistance. Then you repository would have two strategies to cope with things. Perhaps there is an IBulkRepository interface that the repo could (optionally) implement, etc.

榆西 2024-07-21 02:41:50

我同意马克的观点。 我们也采取了与马克几乎相同的方法。 我想这是解决此类问题的标准和最佳方法。 虽然我不太熟悉这里的线程静态业务,所以不能对此提出更多建议。

I agree with Marc here. We too go with almost the same approach that Marc has shown. I guess that's the standard and optimal way to come to solution of such a problem. Though I am not much acquainted with thread static business here, so can't suggest more in that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文