【问题标题】:SQL Anywhere, Entity Framework 4 and TransactionsSQL Anywhere、Entity Framework 4 和事务
【发布时间】:2012-09-07 19:22:45
【问题描述】:

我的程序中有一个使用 Entity Framework 4 EDM 的进程。实体上下文对象包含用于调用存储过程的函数导入。

进程从远程服务器接收一批数据。批处理可以包含我们任何表/数据类型的数据(每种数据类型都存储在自己的表中)。该批次还可以多次包含同一行的数据。它必须将其作为单个插入(对于第一次出现)和一个或多个更新(对于每个后续出现)来处理。因此,存储过程使用 INSERT ... ON EXISTING UPDATE 命令实现了 upsert 操作。

我们的代码基本上确定要调用哪个存储过程,然后使用实体上下文对象的该存储过程的方法调用它。然后整个批处理必须在一个事务中完成,所以我们在批处理开始时调用context.Connection.BeginTransaction()

有一种数据类型有数百万行。我们需要尽快加载这些数据。我正在实现使用SABulkCopy 类导入该数据类型的逻辑。这也需要是已经开始的单个事务的一部分。问题是我需要将SATransaction 传递给SABulkCopy 类的构造函数(无法使用属性对其进行设置)并且我没有SATransactioncontext.Connection.BeginTransaction() 返回 DBTransaction。我试图将其转换为SATransaction,但没有成功。

SABulkCopy对象加入事务的正确方法是什么?

【问题讨论】:

    标签: entity-framework entity-framework-4 transactions sqlanywhere


    【解决方案1】:

    我们放弃了SABulkCopy 课程。事实证明,它不会进行批量加载。它创建一个SACommand 对象,该对象执行INSERT 语句并一次插入一行。而且它的启动效率很低。

    我仍然需要访问与context.Connection.BeginTransaction(). 返回的DBTransaction 相关联的SATransaction,我收到了一些反射代码来回答我发布的另一个问题:

    SATransaction saTransaction = (SATransaction) dbTransaction.GetType() 
                                                               .InvokeMember( "StoreTransaction", 
                                                                              BindingFlags.FlattenHierarchy | BindingFlags.NonPublic   | BindingFlags.InvokeMethod |
                                                                              BindingFlags.Instance         | BindingFlags.GetProperty | BindingFlags.NonPublic, 
                                                                              null, dbTransaction, new object[ 0 ] );
    

    程序做它需要做的事情。不过很遗憾,Microsoft 没有公开 EntityTransaction 类的 StoreTransaction 属性。

    【讨论】:

    • 我知道这是旧的,但你能告诉我你是如何发现 SaBulkCopy 创建和 SACommand 并执行 Insert 语句...?顺便问一下,当您决定放弃 SaBulkCopy 时,您的解决方案是什么?谢谢
    • 是的,这是很久以前的事了。我可能使用过像 .Net Reflector 这样的反编译器来查看反编译的代码,以了解在 SaBulkCopy 期间发生了什么。我认为代码是一个开源项目,所以你可以查一下。对不起,我已经不在那个位置了,所以我不记得了。我似乎记得我们必须编写代码,将数据一次插入一行(无法绕过)到没有索引的临时表中,然后从该表更新主表,然后删除临时表。我们也在一笔交易中完成了这一切。
    • 非常感谢您@Tony Vitabile
    • 我认为 SaBulkCopy 会创建一个SaCommand,插入一行,丢弃SaCommand,然后对每一行重复。我们编写了代码,因此它创建了一个 SaCommand 对象,它将重复用于所有行。对于一两行,改进不大,但对于数百万行,改进将是显着的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多