Skip to content

Commit 2189137

Browse files
author
zzzprojects
committed
Support Oracle for QueryFutureBatch && IncludeOptimized
1 parent 661cb72 commit 2189137

File tree

13 files changed

+772
-162
lines changed

13 files changed

+772
-162
lines changed

src/Z.EntityFramework.Plus.EF5.NET40/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@
1818
[assembly: AssemblyCulture("")]
1919
[assembly: ComVisible(false)]
2020
[assembly: Guid("e4c2af73-caeb-4429-bcb6-0a359484e064")]
21-
[assembly: AssemblyVersion("1.4.18")]
22-
[assembly: AssemblyFileVersion("1.4.18")]
21+
[assembly: AssemblyVersion("1.4.19")]
22+
[assembly: AssemblyFileVersion("1.4.19")]

src/Z.EntityFramework.Plus.EF5.NET40/QueryFuture/QueryFutureBatch.cs

Lines changed: 152 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Collections.Generic;
1010
using System.Data;
1111
using System.Data.Common;
12+
using System.Linq.Expressions;
1213
using System.Reflection;
1314
using System.Text;
1415

@@ -65,7 +66,7 @@ public QueryFutureBatch(DbContext context)
6566
public void ExecuteQueries()
6667
{
6768
#if EF5 || EF6
68-
var connection = (EntityConnection)Context.Connection;
69+
var connection = (EntityConnection) Context.Connection;
6970
#elif EFCORE
7071
var connection = Context.Database.GetDbConnection();
7172
#endif
@@ -135,6 +136,10 @@ protected DbCommand CreateCommandCombined()
135136
var sb = new StringBuilder();
136137
var queryCount = 1;
137138

139+
var isOracle = command.GetType().FullName.Contains("Oracle.DataAccess");
140+
var isOracleManaged = command.GetType().FullName.Contains("Oracle.ManagedDataAccess");
141+
var isOracleDevArt = command.GetType().FullName.Contains("Devart");
142+
138143
foreach (var query in Queries)
139144
{
140145
// GENERATE SQL
@@ -158,43 +163,35 @@ protected DbCommand CreateCommandCombined()
158163
sql = sql.Replace("@" + oldValue, "@" + newValue);
159164
}
160165
#elif EF6
166+
var commandTextAndParameter = query.Query.GetCommandTextAndParameters();
161167

162-
var objectQuery = query.Query;
163-
var stateField = objectQuery.GetType().BaseType.GetField("_state", BindingFlags.NonPublic | BindingFlags.Instance);
164-
var state = stateField.GetValue(objectQuery);
165-
var getExecutionPlanMethod = state.GetType().GetMethod("GetExecutionPlan", BindingFlags.NonPublic | BindingFlags.Instance);
166-
var getExecutionPlan = getExecutionPlanMethod.Invoke(state, new object[] { null });
167-
var prepareEntityCommandMethod = getExecutionPlan.GetType().GetMethod("PrepareEntityCommand", BindingFlags.NonPublic | BindingFlags.Instance);
168-
169-
string sql = "";
170-
using (EntityCommand entityCommand = (EntityCommand) prepareEntityCommandMethod.Invoke(getExecutionPlan, new object[] {objectQuery.Context, objectQuery.Parameters}))
171-
{
172-
var getCommandDefinitionMethod = entityCommand.GetType().GetMethod("GetCommandDefinition", BindingFlags.NonPublic | BindingFlags.Instance);
173-
var getCommandDefinition = getCommandDefinitionMethod.Invoke(entityCommand, new object[0]);
174168

175-
var prepareEntityCommandBeforeExecutionMethod = getCommandDefinition.GetType().GetMethod("PrepareEntityCommandBeforeExecution", BindingFlags.NonPublic | BindingFlags.Instance);
176-
var prepareEntityCommandBeforeExecution = (DbCommand)prepareEntityCommandBeforeExecutionMethod.Invoke(getCommandDefinition, new object[] {entityCommand});
169+
var sql = commandTextAndParameter.Item1;
170+
var parameters = commandTextAndParameter.Item2;
177171

178-
sql = prepareEntityCommandBeforeExecution.CommandText;
179-
var parameters = prepareEntityCommandBeforeExecution.Parameters;
180-
181-
// UPDATE parameter name
182-
foreach (DbParameter parameter in parameters)
172+
// UPDATE parameter name
173+
foreach (DbParameter parameter in parameters)
174+
{
175+
var oldValue = parameter.ParameterName;
176+
if (oldValue.StartsWith("@"))
183177
{
184-
var oldValue = parameter.ParameterName;
185-
if (oldValue.StartsWith("@"))
186-
{
187-
oldValue = oldValue.Substring(1);
188-
}
189-
var newValue = string.Concat("Z_", queryCount, "_", oldValue);
178+
oldValue = oldValue.Substring(1);
179+
}
180+
var newValue = string.Concat("Z_", queryCount, "_", oldValue);
190181

191-
// CREATE parameter
192-
var dbParameter = command.CreateParameter();
193-
dbParameter.ParameterName = newValue;
194-
dbParameter.Value = parameter.Value;
195-
command.Parameters.Add(dbParameter);
182+
// CREATE parameter
183+
var dbParameter = command.CreateParameter();
184+
dbParameter.ParameterName = newValue;
185+
dbParameter.Value = parameter.Value;
186+
command.Parameters.Add(dbParameter);
196187

197-
// REPLACE parameter with new value
188+
// REPLACE parameter with new value
189+
if (isOracle || isOracleManaged || isOracleDevArt)
190+
{
191+
sql = sql.Replace(":" + oldValue, ":" + newValue);
192+
}
193+
else
194+
{
198195
sql = sql.Replace("@" + oldValue, "@" + newValue);
199196
}
200197
}
@@ -206,26 +203,66 @@ protected DbCommand CreateCommandCombined()
206203
var parameters = queryCommand.Parameters;
207204

208205
// UPDATE parameter name
209-
foreach (var parameter in queryContext.ParameterValues)
206+
foreach (var relationalParameter in queryCommand.Parameters)
210207
{
211-
var oldValue = parameter.Key;
208+
var parameter = queryContext.ParameterValues[relationalParameter.InvariantName];
209+
210+
var oldValue = relationalParameter.InvariantName;
212211
var newValue = string.Concat("Z_", queryCount, "_", oldValue);
213212

214213
// CREATE parameter
215214
var dbParameter = command.CreateParameter();
216215
dbParameter.ParameterName = newValue;
217-
dbParameter.Value = parameter.Value;
216+
dbParameter.Value = parameter;
218217
command.Parameters.Add(dbParameter);
219218

220219
// REPLACE parameter with new value
221-
sql = sql.Replace("@" + oldValue, "@" + newValue);
220+
if (isOracle || isOracleManaged || isOracleDevArt)
221+
{
222+
sql = sql.Replace(":" + oldValue, ":" + newValue);
223+
}
224+
else
225+
{
226+
sql = sql.Replace("@" + oldValue, "@" + newValue);
227+
}
222228
}
223229
#endif
224230

225231

226232

227233
sb.AppendLine(string.Concat("-- EF+ Query Future: ", queryCount, " of ", Queries.Count));
228-
sb.AppendLine(sql);
234+
235+
if (isOracle || isOracleManaged || isOracleDevArt)
236+
{
237+
var parameterName = "zzz_cursor_" + queryCount;
238+
sb.AppendLine("open :" + parameterName + " for " + sql);
239+
var param = command.CreateParameter();
240+
param.ParameterName = parameterName;
241+
param.Direction = ParameterDirection.Output;
242+
param.Value = DBNull.Value;
243+
244+
if (isOracle)
245+
{
246+
SetOracleDbType(command.GetType().Assembly, param, 121);
247+
}
248+
else if (isOracleManaged)
249+
{
250+
SetOracleManagedDbType(command.GetType().Assembly, param, 121);
251+
}
252+
else if (isOracleDevArt)
253+
{
254+
SetOracleDevArtDbType(command.GetType().Assembly, param, 7);
255+
}
256+
257+
258+
command.Parameters.Add(param);
259+
}
260+
else
261+
{
262+
sb.AppendLine(sql);
263+
}
264+
265+
229266
sb.Append(";"); // SQL Server, SQL Azure, MySQL
230267
sb.AppendLine();
231268
sb.AppendLine();
@@ -235,7 +272,85 @@ protected DbCommand CreateCommandCombined()
235272

236273
command.CommandText = sb.ToString();
237274

275+
if (isOracle || isOracleManaged || isOracleDevArt)
276+
{
277+
var bindByNameProperty = command.GetType().GetProperty("BindByName") ?? command.GetType().GetProperty("PassParametersByName");
278+
bindByNameProperty.SetValue(command, true, null);
279+
280+
command.CommandText = "BEGIN" + Environment.NewLine + command.CommandText + Environment.NewLine + "END;";
281+
}
282+
238283
return command;
239284
}
285+
286+
private static Action<DbParameter, object> _SetOracleDbType;
287+
private static Action<DbParameter, object> _SetOracleManagedDbType;
288+
private static Action<DbParameter, object> _SetOracleDevArtDbType;
289+
290+
public static void SetOracleManagedDbType(Assembly assembly, DbParameter dbParameter, object type)
291+
{
292+
if (_SetOracleManagedDbType == null)
293+
{
294+
var dbtype = assembly.GetType("Oracle.ManagedDataAccess.Client.OracleDbType");
295+
var dbParameterType = assembly.GetType("Oracle.ManagedDataAccess.Client.OracleParameter");
296+
var propertyInfo = dbParameter.GetType().GetProperty("OracleDbType");
297+
298+
var parameter = Expression.Parameter(typeof(DbParameter));
299+
var parameterConvert = Expression.Convert(parameter, dbParameterType);
300+
var parameterValue = Expression.Parameter(typeof(object));
301+
var parameterValueConvert = Expression.Convert(parameterValue, dbtype);
302+
303+
var property = Expression.Property(parameterConvert, propertyInfo);
304+
var expression = Expression.Assign(property, parameterValueConvert);
305+
306+
_SetOracleManagedDbType = Expression.Lambda<Action<DbParameter, object>>(expression, parameter, parameterValue).Compile();
307+
}
308+
309+
_SetOracleManagedDbType(dbParameter, type);
310+
}
311+
312+
public static void SetOracleDbType(Assembly assembly, DbParameter dbParameter, object type)
313+
{
314+
if (_SetOracleDbType == null)
315+
{
316+
var dbtype = assembly.GetType("Oracle.DataAccess.Client.OracleDbType");
317+
var dbParameterType = assembly.GetType("Oracle.DataAccess.Client.OracleParameter");
318+
var propertyInfo = dbParameter.GetType().GetProperty("OracleDbType");
319+
320+
var parameter = Expression.Parameter(typeof(DbParameter));
321+
var parameterConvert = Expression.Convert(parameter, dbParameterType);
322+
var parameterValue = Expression.Parameter(typeof(object));
323+
var parameterValueConvert = Expression.Convert(parameterValue, dbtype);
324+
325+
var property = Expression.Property(parameterConvert, propertyInfo);
326+
var expression = Expression.Assign(property, parameterValueConvert);
327+
328+
_SetOracleDbType = Expression.Lambda<Action<DbParameter, object>>(expression, parameter, parameterValue).Compile();
329+
}
330+
331+
_SetOracleDbType(dbParameter, type);
332+
}
333+
334+
public static void SetOracleDevArtDbType(Assembly assembly, DbParameter dbParameter, object type)
335+
{
336+
if (_SetOracleDevArtDbType == null)
337+
{
338+
var dbtype = assembly.GetType("Devart.Data.Oracle.OracleDbType");
339+
var dbParameterType = assembly.GetType("Devart.Data.Oracle.OracleParameter");
340+
var propertyInfo = dbParameter.GetType().GetProperty("OracleDbType");
341+
342+
var parameter = Expression.Parameter(typeof(DbParameter));
343+
var parameterConvert = Expression.Convert(parameter, dbParameterType);
344+
var parameterValue = Expression.Parameter(typeof(object));
345+
var parameterValueConvert = Expression.Convert(parameterValue, dbtype);
346+
347+
var property = Expression.Property(parameterConvert, propertyInfo);
348+
var expression = Expression.Assign(property, parameterValueConvert);
349+
350+
_SetOracleDevArtDbType = Expression.Lambda<Action<DbParameter, object>>(expression, parameter, parameterValue).Compile();
351+
}
352+
353+
_SetOracleDevArtDbType(dbParameter, type);
354+
}
240355
}
241356
}

src/Z.EntityFramework.Plus.EF5/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@
1818
[assembly: AssemblyCulture("")]
1919
[assembly: ComVisible(false)]
2020
[assembly: Guid("abcbb878-043c-4957-a334-90e9872e684e")]
21-
[assembly: AssemblyVersion("1.4.18")]
22-
[assembly: AssemblyFileVersion("1.4.18")]
21+
[assembly: AssemblyVersion("1.4.19")]
22+
[assembly: AssemblyFileVersion("1.4.19")]

0 commit comments

Comments
 (0)