English 中文(简体)
从 IDb联结 实例中建立 IData 设计师
原标题:Instantiate IDataAdapter from instance of IDbConnection
  • 时间:2012-05-23 15:49:38
  •  标签:
  • c#

I have an instance of IDbConnection, which can be any connection, Sql, OleDb, etc. I want to make a generic wrapper so I can just send the wrapper a connection and get a nice set of methods for easy manipulation. I have a Query method, I want it to return a DataTable, so I can do

IDataAdapter adapter = new OleDbDataAdapter();
adapter.SelectCommand = myCommand;
DataSet ds = new DataSet();
adapter.Fill(ds);

The problem is I have to use OleDbAdapter and it wouldn t work for SQL, I don t really want to write "driver specific" code. Is there a way I can get a IDataAdapter instance from my instantiated IDbConnection object? I know I can create a command doing

IDbCommand command = _connection.CreateCommand();

认为对IDataAdapter来说 一定有简单的方法来做同样的事情, 这是合乎逻辑的。

编辑:

using (var reader = command.ExecuteReader())
{
    var dataTable = new DataTable();
    dataTable.Load(reader);
}

与其说是我要求的 不如说是个不错的解决方案

问题回答

这是一个粗略的例子,说明你如何利用反射获得适配器。

IDataAdapter GetAdapter(IDbConnection connection) {
    var assembly = connection.GetType().Assembly;
    var @namespace = connection.GetType().Namespace;    

    // Assumes the factory is in the same namespace
    var factoryType = assembly.GetTypes()
                        .Where (x => x.Namespace == @namespace)
                        .Where (x => x.IsSubclassOf(typeof(DbProviderFactory)))
                        .Single();

    // SqlClientFactory and OleDbFactory both have an Instance field.
    var instanceFieldInfo = factoryType.GetField("Instance", BindingFlags.Static | BindingFlags.Public);
    var factory = (DbProviderFactory) instanceFieldInfo.GetValue(null);

    return factory.CreateDataAdapter();
}

我也有同样的问题,我就是这样解决的

private DataSet executeDataQuery(string query, string connection, string provider, out Exception ex) {
        DataSet ds = new DataSet();
        ex = null;
        DbProviderFactory dbFactory = DbProviderFactories.GetFactory(provider);
        IDbConnection dbConnection = dbFactory.CreateConnection();
        dbConnection.ConnectionString = connection;
        using (dbConnection) {
            try {
                IDbDataAdapter dbAdapter = dbFactory.CreateDataAdapter();
                IDbCommand dbCommand = dbConnection.CreateCommand();
                dbCommand.CommandText = query;
                dbCommand.CommandType = CommandType.Text;
                dbAdapter.SelectCommand = dbCommand;
                dbAdapter.Fill(ds);
            }
            catch (Exception exc) {
                ex = exc;
            }
            finally {
                if (dbConnection.State == ConnectionState.Open) {
                    dbConnection.Close();
                }
            }
        }
        return ds;
    }




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签