Skip to content

Commit bf6c995

Browse files
author
zzzprojects
committed
Update to v1.5.2
Update to v1.5.2
1 parent f7c549b commit bf6c995

File tree

23 files changed

+394
-59
lines changed

23 files changed

+394
-59
lines changed

src/Z.EntityFramework.Plus.EF5.NET40/BatchDelete/BatchDelete.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,16 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
315315
var isSqlCe = command.GetType().Name == "SqlCeCommand";
316316
var isOracle = command.GetType().Namespace.Contains("Oracle");
317317

318+
// Oracle BindByName
319+
if (isOracle)
320+
{
321+
var bindByNameProperty = command.GetType().GetProperty("BindByName") ?? command.GetType().GetProperty("PassParametersByName");
322+
if (bindByNameProperty != null)
323+
{
324+
bindByNameProperty.SetValue(command, true, null);
325+
}
326+
}
327+
318328
// GET mapping
319329
var mapping = entity.Info.EntityTypeMapping.MappingFragment;
320330
var store = mapping.StoreEntitySet;

src/Z.EntityFramework.Plus.EF5.NET40/BatchUpdate/BatchUpdate.cs

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ WHERE EXISTS ( SELECT 1 FROM ({Select}) AS B
4949
WHERE {PrimaryKeys}
5050
)
5151
";
52+
internal const string CommandTextOracleTemplate = @"
53+
UPDATE {TableName}
54+
SET {SetValue}
55+
WHERE EXISTS ( SELECT 1 FROM ({Select}) B
56+
WHERE {PrimaryKeys}
57+
)
58+
";
5259

5360
internal const string CommandTextTemplate_MySQL = @"
5461
UPDATE {TableName} AS A
@@ -199,6 +206,33 @@ public int Execute<T>(IQueryable<T> query, Expression<Func<T, T>> updateFactory)
199206
}
200207
}
201208
#elif EFCORE
209+
if (BatchUpdateManager.InMemoryDbContextFactory != null && query.IsInMemoryQueryContext())
210+
{
211+
var context = BatchUpdateManager.InMemoryDbContextFactory();
212+
213+
var list = query.ToList();
214+
var compiled = updateFactory.Compile();
215+
var memberBindings = ((MemberInitExpression)updateFactory.Body).Bindings;
216+
var accessors = memberBindings
217+
.Select(x => x.Member.Name)
218+
.Select(x => new PropertyOrFieldAccessor(typeof(T).GetProperty(x, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)))
219+
.ToList();
220+
221+
foreach (var item in list)
222+
{
223+
var newItem = compiled(item);
224+
225+
foreach (var accessor in accessors)
226+
{
227+
var value = accessor.GetValue(newItem);
228+
accessor.SetValue(item, value);
229+
}
230+
}
231+
232+
context.SaveChanges();
233+
return list.Count;
234+
}
235+
202236
var dbContext = query.GetDbContext();
203237
var entity = dbContext.Model.FindEntityType(typeof(T));
204238

@@ -253,6 +287,17 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
253287
var command = query.Context.CreateStoreCommand();
254288
bool isMySql = command.GetType().FullName.Contains("MySql");
255289
var isSqlCe = command.GetType().Name == "SqlCeCommand";
290+
var isOracle = command.GetType().Namespace.Contains("Oracle");
291+
292+
// Oracle BindByName
293+
if (isOracle)
294+
{
295+
var bindByNameProperty = command.GetType().GetProperty("BindByName") ?? command.GetType().GetProperty("PassParametersByName");
296+
if (bindByNameProperty != null)
297+
{
298+
bindByNameProperty.SetValue(command, true, null);
299+
}
300+
}
256301

257302
// GET mapping
258303
var mapping = entity.Info.EntityTypeMapping.MappingFragment;
@@ -268,6 +313,12 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
268313
{
269314
tableName = string.Concat("[", store.Table, "]");
270315
}
316+
else if (isOracle)
317+
{
318+
tableName = string.IsNullOrEmpty(store.Schema) || store.Schema == "dbo" ?
319+
string.Concat("\"", store.Table, "\"") :
320+
string.Concat("\"", store.Schema, "\".\"", store.Table, "\"");
321+
}
271322
else
272323
{
273324
tableName = string.IsNullOrEmpty(store.Schema) ?
@@ -299,6 +350,7 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
299350
CommandTextWhileDelayTemplate :
300351
CommandTextWhileTemplate :
301352
#endif
353+
isOracle ? CommandTextOracleTemplate :
302354
isMySql ? CommandTextTemplate_MySQL :
303355
isSqlCe ? CommandTextTemplateSqlCe :
304356
CommandTextTemplate;
@@ -313,20 +365,29 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
313365

314366
if (isSqlCe)
315367
{
316-
primaryKeys = string.Join(Environment.NewLine + "AND ", columnKeys.Select(x => string.Concat(tableName + ".", EscapeName(x, isMySql), " = B.", EscapeName(x, isMySql), "")));
368+
primaryKeys = string.Join(Environment.NewLine + "AND ", columnKeys.Select(x => string.Concat(tableName + ".", EscapeName(x, isMySql, isOracle), " = B.", EscapeName(x, isMySql, isOracle), "")));
317369

318370
setValues = string.Join("," + Environment.NewLine, values.Select((x, i) => x.Item2 is ConstantExpression ?
319-
string.Concat(EscapeName(x.Item1, isMySql), " = ", ((ConstantExpression) x.Item2).Value.ToString().Replace("B.[", "[")) :
320-
string.Concat(EscapeName(x.Item1, isMySql), " = @zzz_BatchUpdate_", i)));
371+
string.Concat(EscapeName(x.Item1, isMySql, isOracle), " = ", ((ConstantExpression) x.Item2).Value.ToString().Replace("B.[", "[")) :
372+
string.Concat(EscapeName(x.Item1, isMySql, isOracle), " = @zzz_BatchUpdate_", i)));
373+
}
374+
else if (isOracle)
375+
{
376+
primaryKeys = string.Join(Environment.NewLine + "AND ", columnKeys.Select(x => string.Concat(tableName + ".", EscapeName(x, isMySql, isOracle), " = B.", EscapeName(x, isMySql, isOracle), "")));
377+
378+
// GET updateSetValues
379+
setValues = string.Join("," + Environment.NewLine, values.Select((x, i) => x.Item2 is ConstantExpression ?
380+
string.Concat(EscapeName(x.Item1, isMySql, isOracle), " = ", ((ConstantExpression)x.Item2).Value) :
381+
string.Concat(EscapeName(x.Item1, isMySql, isOracle), " = :zzz_BatchUpdate_", i)));
321382
}
322383
else
323384
{
324-
primaryKeys = string.Join(Environment.NewLine + "AND ", columnKeys.Select(x => string.Concat("A.", EscapeName(x, isMySql), " = B.", EscapeName(x, isMySql), "")));
385+
primaryKeys = string.Join(Environment.NewLine + "AND ", columnKeys.Select(x => string.Concat("A.", EscapeName(x, isMySql, isOracle), " = B.", EscapeName(x, isMySql, isOracle), "")));
325386

326387
// GET updateSetValues
327388
setValues = string.Join("," + Environment.NewLine, values.Select((x, i) => x.Item2 is ConstantExpression ?
328-
string.Concat("A.", EscapeName(x.Item1, isMySql), " = ", ((ConstantExpression) x.Item2).Value) :
329-
string.Concat("A.", EscapeName(x.Item1, isMySql), " = @zzz_BatchUpdate_", i)));
389+
string.Concat("A.", EscapeName(x.Item1, isMySql, isOracle), " = ", ((ConstantExpression) x.Item2).Value) :
390+
string.Concat("A.", EscapeName(x.Item1, isMySql, isOracle), " = @zzz_BatchUpdate_", i)));
330391
}
331392

332393
// REPLACE template
@@ -369,8 +430,10 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
369430
continue;
370431
}
371432

433+
var parameterPrefix = isOracle ? ":" : "@";
434+
372435
var parameter = command.CreateParameter();
373-
parameter.ParameterName = "@zzz_BatchUpdate_" + i;
436+
parameter.ParameterName = parameterPrefix + "zzz_BatchUpdate_" + i;
374437
parameter.Value = values[i].Item2 ?? DBNull.Value;
375438
command.Parameters.Add(parameter);
376439
}
@@ -686,9 +749,11 @@ public List<Tuple<string, object>> GetInnerValues<T>(IQueryable<T> query, Expres
686749
return destinationValues;
687750
}
688751

689-
public string EscapeName(string name, bool isMySql)
752+
public string EscapeName(string name, bool isMySql, bool isOracle)
690753
{
691-
return isMySql ? string.Concat("`", name, "`") : string.Concat("[", name, "]");
754+
return isMySql ? string.Concat("`", name, "`") :
755+
isOracle ? string.Concat("\"", name, "\"") :
756+
string.Concat("[", name, "]");
692757
}
693758

694759
public Dictionary<string, object> ResolveUpdateFromQueryDictValues<T>(Expression<Func<T, T>> updateFactory)

src/Z.EntityFramework.Plus.EF5.NET40/BatchUpdate/BatchUpdateManager.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
using System;
99

10+
#if EFCORE
11+
using Microsoft.EntityFrameworkCore;
12+
#endif
13+
1014
namespace Z.EntityFramework.Plus
1115
{
1216
/// <summary>Manage EF+ Batch Update Configuration.</summary>
@@ -15,5 +19,12 @@ public class BatchUpdateManager
1519
/// <summary>Gets or sets the batch update builder to change default configuration.</summary>
1620
/// <value>The batch update builder to change default configuration.</value>
1721
public static Action<BatchUpdate> BatchUpdateBuilder { get; set; }
22+
23+
#if EFCORE
24+
25+
/// <summary>Gets or sets the factory to create an InMemory DbContext.</summary>
26+
/// <value>The factory to create an InMemory DbContext.</value>
27+
public static Func<DbContext> InMemoryDbContextFactory { get; set; }
28+
#endif
1829
}
1930
}

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.45")]
22-
[assembly: AssemblyFileVersion("1.4.45")]
21+
[assembly: AssemblyVersion("1.5.2")]
22+
[assembly: AssemblyFileVersion("1.5.2")]

src/Z.EntityFramework.Plus.EF5/BatchDelete/BatchDelete.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,16 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
315315
var isSqlCe = command.GetType().Name == "SqlCeCommand";
316316
var isOracle = command.GetType().Namespace.Contains("Oracle");
317317

318+
// Oracle BindByName
319+
if (isOracle)
320+
{
321+
var bindByNameProperty = command.GetType().GetProperty("BindByName") ?? command.GetType().GetProperty("PassParametersByName");
322+
if (bindByNameProperty != null)
323+
{
324+
bindByNameProperty.SetValue(command, true, null);
325+
}
326+
}
327+
318328
// GET mapping
319329
var mapping = entity.Info.EntityTypeMapping.MappingFragment;
320330
var store = mapping.StoreEntitySet;

src/Z.EntityFramework.Plus.EF5/BatchUpdate/BatchUpdate.cs

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ WHERE EXISTS ( SELECT 1 FROM ({Select}) AS B
4949
WHERE {PrimaryKeys}
5050
)
5151
";
52+
internal const string CommandTextOracleTemplate = @"
53+
UPDATE {TableName}
54+
SET {SetValue}
55+
WHERE EXISTS ( SELECT 1 FROM ({Select}) B
56+
WHERE {PrimaryKeys}
57+
)
58+
";
5259

5360
internal const string CommandTextTemplate_MySQL = @"
5461
UPDATE {TableName} AS A
@@ -199,6 +206,33 @@ public int Execute<T>(IQueryable<T> query, Expression<Func<T, T>> updateFactory)
199206
}
200207
}
201208
#elif EFCORE
209+
if (BatchUpdateManager.InMemoryDbContextFactory != null && query.IsInMemoryQueryContext())
210+
{
211+
var context = BatchUpdateManager.InMemoryDbContextFactory();
212+
213+
var list = query.ToList();
214+
var compiled = updateFactory.Compile();
215+
var memberBindings = ((MemberInitExpression)updateFactory.Body).Bindings;
216+
var accessors = memberBindings
217+
.Select(x => x.Member.Name)
218+
.Select(x => new PropertyOrFieldAccessor(typeof(T).GetProperty(x, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)))
219+
.ToList();
220+
221+
foreach (var item in list)
222+
{
223+
var newItem = compiled(item);
224+
225+
foreach (var accessor in accessors)
226+
{
227+
var value = accessor.GetValue(newItem);
228+
accessor.SetValue(item, value);
229+
}
230+
}
231+
232+
context.SaveChanges();
233+
return list.Count;
234+
}
235+
202236
var dbContext = query.GetDbContext();
203237
var entity = dbContext.Model.FindEntityType(typeof(T));
204238

@@ -253,6 +287,17 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
253287
var command = query.Context.CreateStoreCommand();
254288
bool isMySql = command.GetType().FullName.Contains("MySql");
255289
var isSqlCe = command.GetType().Name == "SqlCeCommand";
290+
var isOracle = command.GetType().Namespace.Contains("Oracle");
291+
292+
// Oracle BindByName
293+
if (isOracle)
294+
{
295+
var bindByNameProperty = command.GetType().GetProperty("BindByName") ?? command.GetType().GetProperty("PassParametersByName");
296+
if (bindByNameProperty != null)
297+
{
298+
bindByNameProperty.SetValue(command, true, null);
299+
}
300+
}
256301

257302
// GET mapping
258303
var mapping = entity.Info.EntityTypeMapping.MappingFragment;
@@ -268,6 +313,12 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
268313
{
269314
tableName = string.Concat("[", store.Table, "]");
270315
}
316+
else if (isOracle)
317+
{
318+
tableName = string.IsNullOrEmpty(store.Schema) || store.Schema == "dbo" ?
319+
string.Concat("\"", store.Table, "\"") :
320+
string.Concat("\"", store.Schema, "\".\"", store.Table, "\"");
321+
}
271322
else
272323
{
273324
tableName = string.IsNullOrEmpty(store.Schema) ?
@@ -299,6 +350,7 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
299350
CommandTextWhileDelayTemplate :
300351
CommandTextWhileTemplate :
301352
#endif
353+
isOracle ? CommandTextOracleTemplate :
302354
isMySql ? CommandTextTemplate_MySQL :
303355
isSqlCe ? CommandTextTemplateSqlCe :
304356
CommandTextTemplate;
@@ -313,20 +365,29 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
313365

314366
if (isSqlCe)
315367
{
316-
primaryKeys = string.Join(Environment.NewLine + "AND ", columnKeys.Select(x => string.Concat(tableName + ".", EscapeName(x, isMySql), " = B.", EscapeName(x, isMySql), "")));
368+
primaryKeys = string.Join(Environment.NewLine + "AND ", columnKeys.Select(x => string.Concat(tableName + ".", EscapeName(x, isMySql, isOracle), " = B.", EscapeName(x, isMySql, isOracle), "")));
317369

318370
setValues = string.Join("," + Environment.NewLine, values.Select((x, i) => x.Item2 is ConstantExpression ?
319-
string.Concat(EscapeName(x.Item1, isMySql), " = ", ((ConstantExpression) x.Item2).Value.ToString().Replace("B.[", "[")) :
320-
string.Concat(EscapeName(x.Item1, isMySql), " = @zzz_BatchUpdate_", i)));
371+
string.Concat(EscapeName(x.Item1, isMySql, isOracle), " = ", ((ConstantExpression) x.Item2).Value.ToString().Replace("B.[", "[")) :
372+
string.Concat(EscapeName(x.Item1, isMySql, isOracle), " = @zzz_BatchUpdate_", i)));
373+
}
374+
else if (isOracle)
375+
{
376+
primaryKeys = string.Join(Environment.NewLine + "AND ", columnKeys.Select(x => string.Concat(tableName + ".", EscapeName(x, isMySql, isOracle), " = B.", EscapeName(x, isMySql, isOracle), "")));
377+
378+
// GET updateSetValues
379+
setValues = string.Join("," + Environment.NewLine, values.Select((x, i) => x.Item2 is ConstantExpression ?
380+
string.Concat(EscapeName(x.Item1, isMySql, isOracle), " = ", ((ConstantExpression)x.Item2).Value) :
381+
string.Concat(EscapeName(x.Item1, isMySql, isOracle), " = :zzz_BatchUpdate_", i)));
321382
}
322383
else
323384
{
324-
primaryKeys = string.Join(Environment.NewLine + "AND ", columnKeys.Select(x => string.Concat("A.", EscapeName(x, isMySql), " = B.", EscapeName(x, isMySql), "")));
385+
primaryKeys = string.Join(Environment.NewLine + "AND ", columnKeys.Select(x => string.Concat("A.", EscapeName(x, isMySql, isOracle), " = B.", EscapeName(x, isMySql, isOracle), "")));
325386

326387
// GET updateSetValues
327388
setValues = string.Join("," + Environment.NewLine, values.Select((x, i) => x.Item2 is ConstantExpression ?
328-
string.Concat("A.", EscapeName(x.Item1, isMySql), " = ", ((ConstantExpression) x.Item2).Value) :
329-
string.Concat("A.", EscapeName(x.Item1, isMySql), " = @zzz_BatchUpdate_", i)));
389+
string.Concat("A.", EscapeName(x.Item1, isMySql, isOracle), " = ", ((ConstantExpression) x.Item2).Value) :
390+
string.Concat("A.", EscapeName(x.Item1, isMySql, isOracle), " = @zzz_BatchUpdate_", i)));
330391
}
331392

332393
// REPLACE template
@@ -369,8 +430,10 @@ internal DbCommand CreateCommand<T>(ObjectQuery query, SchemaEntityType<T> entit
369430
continue;
370431
}
371432

433+
var parameterPrefix = isOracle ? ":" : "@";
434+
372435
var parameter = command.CreateParameter();
373-
parameter.ParameterName = "@zzz_BatchUpdate_" + i;
436+
parameter.ParameterName = parameterPrefix + "zzz_BatchUpdate_" + i;
374437
parameter.Value = values[i].Item2 ?? DBNull.Value;
375438
command.Parameters.Add(parameter);
376439
}
@@ -686,9 +749,11 @@ public List<Tuple<string, object>> GetInnerValues<T>(IQueryable<T> query, Expres
686749
return destinationValues;
687750
}
688751

689-
public string EscapeName(string name, bool isMySql)
752+
public string EscapeName(string name, bool isMySql, bool isOracle)
690753
{
691-
return isMySql ? string.Concat("`", name, "`") : string.Concat("[", name, "]");
754+
return isMySql ? string.Concat("`", name, "`") :
755+
isOracle ? string.Concat("\"", name, "\"") :
756+
string.Concat("[", name, "]");
692757
}
693758

694759
public Dictionary<string, object> ResolveUpdateFromQueryDictValues<T>(Expression<Func<T, T>> updateFactory)

src/Z.EntityFramework.Plus.EF5/BatchUpdate/BatchUpdateManager.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
using System;
99

10+
#if EFCORE
11+
using Microsoft.EntityFrameworkCore;
12+
#endif
13+
1014
namespace Z.EntityFramework.Plus
1115
{
1216
/// <summary>Manage EF+ Batch Update Configuration.</summary>
@@ -15,5 +19,12 @@ public class BatchUpdateManager
1519
/// <summary>Gets or sets the batch update builder to change default configuration.</summary>
1620
/// <value>The batch update builder to change default configuration.</value>
1721
public static Action<BatchUpdate> BatchUpdateBuilder { get; set; }
22+
23+
#if EFCORE
24+
25+
/// <summary>Gets or sets the factory to create an InMemory DbContext.</summary>
26+
/// <value>The factory to create an InMemory DbContext.</value>
27+
public static Func<DbContext> InMemoryDbContextFactory { get; set; }
28+
#endif
1829
}
1930
}

0 commit comments

Comments
 (0)