Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我不能将ServiceStack或MLite中的IDbTransaction强制转换为DbTransaction?_C#_Sqlite_<img Src="//i.stack.imgur.com/WM7S8.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">ormlite Servicestack - Fatal编程技术网 ormlite-servicestack,C#,Sqlite,ormlite Servicestack" /> ormlite-servicestack,C#,Sqlite,ormlite Servicestack" />

C# 为什么我不能将ServiceStack或MLite中的IDbTransaction强制转换为DbTransaction?

C# 为什么我不能将ServiceStack或MLite中的IDbTransaction强制转换为DbTransaction?,c#,sqlite,ormlite-servicestack,C#,Sqlite,ormlite Servicestack,我使用的是ServiceStack.Ormlite v3.9.71,在打开Ormlite SQLite事务的地方有以下代码,假设我想在代码中其他地方的命令中使用此事务: var connFactory = new OrmLiteConnectionFactory("ConnectionString", SqliteOrmLiteDialectProvider.Instance) using (IDbConnection db = connFactory.Open()) // using var

我使用的是
ServiceStack.Ormlite v3.9.71
,在打开Ormlite SQLite事务的地方有以下代码,假设我想在代码中其他地方的命令中使用此事务:

var connFactory = new OrmLiteConnectionFactory("ConnectionString", SqliteOrmLiteDialectProvider.Instance)
using (IDbConnection db = connFactory.Open()) // using var doesn't make a difference
using (IDbTransaction tran = db.OpenTransaction()) // using var or even db.BeginTransaction() doesn't make a difference
{
    // I do lots of boring stuff
    ...

    // Somewhere else in the code
    using (var cmd = db.CreateCommand())
    {
        cmd.Transaction = tran; // get an error
    }
}    
但是,当我这样做时,我得到:

A first chance exception of type 'System.InvalidCastException' occurred in System.Data.dll

Additional information: Unable to cast object of type 'ServiceStack.OrmLite.OrmLiteTransaction' to type 'System.Data.Common.DbTransaction'. 
和堆栈跟踪:

   at System.Data.Common.DbCommand.System.Data.IDbCommand.set_Transaction(IDbTransaction value)

我想这是由于OrmliTransaction包装器造成的,我如何才能到达事务?

更新

OrmLiteConnection将返回一个SqliteCommand,这意味着无法设置该命令的事务属性,因为该命令需要一个SqliteTransaction对象。即使您尝试设置IDbCommand.Transaction,您也将调用
DbCommand.Transaction
setter来检查传递的对象是否是DbTransaction对象

修复方法是简单地不设置事务属性,因为如果已使用
db.OpenTransaction
打开事务,则
db.CreateCommand
会自行设置事务属性

原创

我认为您应该遵循@Mangus的建议,使用
var
,而不是强制转换到接口

检查的实现,它似乎在使用Mono.Data.Sqlite。Mono.Data.Sqlite类继承自抽象的
DbXXX
类,但用自己的类隐藏基本实现

并有以下签名:

public new SqliteCommand CreateCommand()
{
...
}

public new SqliteTransaction Transaction
{
...
}
通过强制转换到在DbConnection中调用基本实现的接口,DbCommand类代替了Mono.Data.Sqlite中的新实现。这意味着
OpenTransaction
将返回一个
DbTransaction
派生的对象,而不是ORMLITransaction对象

以下代码应该可以工作:

var connFactory = new OrmLiteConnectionFactory("ConnectionString", SqliteOrmLiteDialectProvider.Instance)
using (var db = connFactory.Open())
using (var tran = db.OpenTransaction()) // or even db.BeginTransaction()
{
    // I do lots of boring stuff
    ...

    // Somewhere else in the code
    using (var cmd = db.CreateCommand())
    {
        cmd.Transaction = tran; 
    }
}    
自.NET 2.0以来的ADO.NET提供程序预计将从
DbXXX
抽象类派生,而不是实现.NET 1.1接口,如
IDbConnection


在您的例子中,OrmLite破坏了预期的行为,导致与Mono.Data.Sqlite意外的成员隐藏冲突。否则你不会注意到任何东西。

更新

OrmLiteConnection将返回一个SqliteCommand,这意味着无法设置该命令的事务属性,因为该命令需要一个SqliteTransaction对象。即使您尝试设置IDbCommand.Transaction,您也将调用
DbCommand.Transaction
setter来检查传递的对象是否是DbTransaction对象

修复方法是简单地不设置事务属性,因为如果已使用
db.OpenTransaction
打开事务,则
db.CreateCommand
会自行设置事务属性

原创

我认为您应该遵循@Mangus的建议,使用
var
,而不是强制转换到接口

检查的实现,它似乎在使用Mono.Data.Sqlite。Mono.Data.Sqlite类继承自抽象的
DbXXX
类,但用自己的类隐藏基本实现

并有以下签名:

public new SqliteCommand CreateCommand()
{
...
}

public new SqliteTransaction Transaction
{
...
}
通过强制转换到在DbConnection中调用基本实现的接口,DbCommand类代替了Mono.Data.Sqlite中的新实现。这意味着
OpenTransaction
将返回一个
DbTransaction
派生的对象,而不是ORMLITransaction对象

以下代码应该可以工作:

var connFactory = new OrmLiteConnectionFactory("ConnectionString", SqliteOrmLiteDialectProvider.Instance)
using (var db = connFactory.Open())
using (var tran = db.OpenTransaction()) // or even db.BeginTransaction()
{
    // I do lots of boring stuff
    ...

    // Somewhere else in the code
    using (var cmd = db.CreateCommand())
    {
        cmd.Transaction = tran; 
    }
}    
自.NET 2.0以来的ADO.NET提供程序预计将从
DbXXX
抽象类派生,而不是实现.NET 1.1接口,如
IDbConnection


在您的例子中,OrmLite破坏了预期的行为,导致与Mono.Data.Sqlite意外的成员隐藏冲突。否则您不会注意到任何东西。

OrmLite提供了ToDbTransaction扩展方法

public static IDbTransaction ToDbTransaction(this IDbTransaction dbTrans)
    {
        var hasDbTrans = dbTrans as IHasDbTransaction;
        return hasDbTrans != null
            ? hasDbTrans.Transaction
            : dbTrans;
    }
您可以像这样在代码中使用它

cmd.Transaction = tran.ToDbTransaction()

希望它能解决您的问题。

OrmLite提供了ToDbTransaction扩展方法

public static IDbTransaction ToDbTransaction(this IDbTransaction dbTrans)
    {
        var hasDbTrans = dbTrans as IHasDbTransaction;
        return hasDbTrans != null
            ? hasDbTrans.Transaction
            : dbTrans;
    }
您可以像这样在代码中使用它

cmd.Transaction = tran.ToDbTransaction()

希望它能解决您的问题。

什么类型的
db
,您使用的是哪家连接工厂?(即OpenTransaction不是普通IDbConnection接口的一部分)您使用的是哪个版本的OrmLite?tmpTran的类型是什么?它是在哪里创建的?@PanagiotisKanavos,Added/Updated,我的上一次更新弄乱了代码尝试使用
使用(IDbConnection db=connFactory.Open())
更改为
使用(var db=connFactory.Open())
下一行相同。可能不使用该接口的
CreateCommand
版本会重新运行一个可以接受
或mliteransaction
@Mangus的命令,但对此不确定。Ormliteransaction实现IDbTransaction,但
cmd.Transaction
似乎期望使用
DbCommand
,即使其类型是IDbTransaction。在内部,SS使用
Mono.Data.Sqlite
。可能是这个驱动程序使用了DbTransaction?什么类型的数据库是
db
,您使用的是哪个连接工厂?(即OpenTransaction不是普通IDbConnection接口的一部分)您使用的是哪个版本的OrmLite?tmpTran的类型是什么?它是在哪里创建的?@PanagiotisKanavos,Added/Updated,我的上一次更新弄乱了代码尝试使用
使用(IDbConnection db=connFactory.Open())
更改为
使用(var db=connFactory.Open())
下一行相同。可能不使用该接口的
CreateCommand
版本会重新运行一个可以接受
或mliteransaction
@Mangus的命令,但对此不确定。Ormliteransaction实现IDbTransaction,但
cmd.Transaction
似乎期望使用
DbCommand
,即使其类型是IDbTransaction。在内部,SS使用
Mono.Data.Sqlite
。可能是这个驱动程序使用了DbTransaction?不,它不起作用,我原来的帖子中确实有
var
关键字,但为了清楚起见,我删除了它,