zhaolei
2020-11-20 921de2254ff5712a44ed8575ee8efe34252f6603
commit | author | age
921de2 1 using System;
Z 2 using System.Data.Common;
3 using System.Reflection;
4
5 namespace PetaPoco
6 {
7     /* 
8     Thanks to Adam Schroder (@schotime) for this.
9     
10     This extra file provides an implementation of DbProviderFactory for early versions of the Oracle
11     drivers that don't include include it.  For later versions of Oracle, the standard OracleProviderFactory
12     class should work fine
13     
14     Uses reflection to load Oracle.DataAccess assembly and in-turn create connections and commands
15     
16     Currently untested.
17     
18     Usage:   
19         
20             new PetaPoco.Database("<connstring>", new PetaPoco.OracleProvider())
21     
22     Or in your app/web config (be sure to change ASSEMBLYNAME to the name of your 
23     assembly containing OracleProvider.cs)
24     
25         <connectionStrings>
26             <add
27                 name="oracle"
28                 connectionString="WHATEVER"
29                 providerName="Oracle"
30                 />
31         </connectionStrings>
32
33         <system.data>
34             <DbProviderFactories>
35                 <add name="PetaPoco Oracle Provider" invariant="Oracle" description="PetaPoco Oracle Provider" 
36                                 type="PetaPoco.OracleProvider, ASSEMBLYNAME" />
37             </DbProviderFactories>
38         </system.data>
39
40      */
41
42     public class OracleProvider : DbProviderFactory
43     {
44         private const string _assemblyName = "Oracle.DataAccess";
45         private const string _connectionTypeName = "Oracle.DataAccess.Client.OracleConnection";
46         private const string _commandTypeName = "Oracle.DataAccess.Client.OracleCommand";
47         private static Type _connectionType;
48         private static Type _commandType;
49
50         // Required for DbProviderFactories.GetFactory() to work.
51         public static OracleProvider Instance = new OracleProvider();
52
53         public OracleProvider()
54         {
55             _connectionType = TypeFromAssembly(_connectionTypeName, _assemblyName);
56             _commandType = TypeFromAssembly(_commandTypeName, _assemblyName);
57             if (_connectionType == null)
58                 throw new InvalidOperationException("Can't find Connection type: " + _connectionTypeName);
59         }
60
61         public override DbConnection CreateConnection()
62         {
63             return (DbConnection) Activator.CreateInstance(_connectionType);
64         }
65
66         public override DbCommand CreateCommand()
67         {
68             DbCommand command = (DbCommand) Activator.CreateInstance(_commandType);
69
70             var oracleCommandBindByName = _commandType.GetProperty("BindByName");
71             oracleCommandBindByName.SetValue(command, true, null);
72
73             return command;
74         }
75
76         public static Type TypeFromAssembly(string typeName, string assemblyName)
77         {
78             try
79             {
80                 // Try to get the type from an already loaded assembly
81                 Type type = Type.GetType(typeName);
82
83                 if (type != null)
84                 {
85                     return type;
86                 }
87
88                 if (assemblyName == null)
89                 {
90                     // No assembly was specified for the type, so just fail
91                     string message = "Could not load type " + typeName + ". Possible cause: no assembly name specified.";
92                     throw new TypeLoadException(message);
93                 }
94
95                 Assembly assembly = Assembly.Load(assemblyName);
96
97                 if (assembly == null)
98                 {
99                     throw new InvalidOperationException("Can't find assembly: " + assemblyName);
100                 }
101
102                 type = assembly.GetType(typeName);
103
104                 if (type == null)
105                 {
106                     return null;
107                 }
108
109                 return type;
110             }
111             catch (Exception)
112             {
113                 return null;
114             }
115         }
116     }
117 }