Added support for With No Lock
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -29,11 +29,13 @@ build/
|
|||||||
bld/
|
bld/
|
||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Oo]bj/*
|
|
||||||
[Oo]ut/
|
[Oo]ut/
|
||||||
msbuild.log
|
msbuild.log
|
||||||
msbuild.err
|
msbuild.err
|
||||||
msbuild.wrn
|
msbuild.wrn
|
||||||
|
*/[Bb]in/
|
||||||
|
*/[Oo]bj/
|
||||||
|
*/[Oo]ut/
|
||||||
|
|
||||||
# Visual Studio 2015
|
# Visual Studio 2015
|
||||||
.vs/
|
.vs/
|
||||||
|
|||||||
@@ -33,33 +33,32 @@
|
|||||||
* * DYNAMORM_OMMIT_TRYPARSE - Remove TryParse helpers (also applies DYNAMORM_OMMIT_GENERICEXECUTION)
|
* * DYNAMORM_OMMIT_TRYPARSE - Remove TryParse helpers (also applies DYNAMORM_OMMIT_GENERICEXECUTION)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using DynamORM.Builders.Extensions;
|
||||||
using System.Collections;
|
using DynamORM.Builders.Implementation;
|
||||||
|
using DynamORM.Builders;
|
||||||
|
using DynamORM.Helpers.Dynamics;
|
||||||
|
using DynamORM.Helpers;
|
||||||
|
using DynamORM.Mapper;
|
||||||
|
using DynamORM.Validation;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Data;
|
using System.Collections;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
|
using System.Data;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using DynamORM.Builders;
|
using System.Text;
|
||||||
using DynamORM.Builders.Extensions;
|
using System;
|
||||||
using DynamORM.Builders.Implementation;
|
|
||||||
using DynamORM.Helpers;
|
|
||||||
using DynamORM.Helpers.Dynamics;
|
|
||||||
using DynamORM.Mapper;
|
|
||||||
using DynamORM.Validation;
|
|
||||||
|
|
||||||
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "This is a generated file which generates all the necessary support classes.")]
|
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "This is a generated file which generates all the necessary support classes.")]
|
||||||
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1403:FileMayOnlyContainASingleNamespace", Justification = "This is a generated file which generates all the necessary support classes.")]
|
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1403:FileMayOnlyContainASingleNamespace", Justification = "This is a generated file which generates all the necessary support classes.")]
|
||||||
|
|
||||||
namespace DynamORM
|
namespace DynamORM
|
||||||
{
|
{
|
||||||
/// <summary>Cache data reader in memory.</summary>
|
/// <summary>Cache data reader in memory.</summary>
|
||||||
@@ -3566,6 +3565,9 @@ namespace DynamORM
|
|||||||
/// <summary>Database support stored procedures (EXEC procedure ...).</summary>
|
/// <summary>Database support stored procedures (EXEC procedure ...).</summary>
|
||||||
SupportStoredProcedures = 0x00000100,
|
SupportStoredProcedures = 0x00000100,
|
||||||
|
|
||||||
|
/// <summary>Database support with no lock syntax.</summary>
|
||||||
|
SupportNoLock = 0x00001000,
|
||||||
|
|
||||||
/// <summary>Debug option allowing to enable command dumps by default.</summary>
|
/// <summary>Debug option allowing to enable command dumps by default.</summary>
|
||||||
DumpCommands = 0x01000000,
|
DumpCommands = 0x01000000,
|
||||||
}
|
}
|
||||||
@@ -4531,7 +4533,7 @@ namespace DynamORM
|
|||||||
param.Scale,
|
param.Scale,
|
||||||
param.Precision,
|
param.Precision,
|
||||||
param.Scale,
|
param.Scale,
|
||||||
param.Value is byte[] ? ConvertByteArrayToHexString((byte[])param.Value) : param.Value ?? "NULL",
|
param.Value is byte[]? ConvertByteArrayToHexString((byte[])param.Value) : param.Value ?? "NULL",
|
||||||
param.Value != null ? param.Value.GetType().Name : "DBNull");
|
param.Value != null ? param.Value.GetType().Name : "DBNull");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7417,6 +7419,9 @@ namespace DynamORM
|
|||||||
/// <summary>Gets table alias.</summary>
|
/// <summary>Gets table alias.</summary>
|
||||||
string Alias { get; }
|
string Alias { get; }
|
||||||
|
|
||||||
|
/// <summary>Gets table no lock status.</summary>
|
||||||
|
bool NoLock { get; }
|
||||||
|
|
||||||
/// <summary>Gets table schema.</summary>
|
/// <summary>Gets table schema.</summary>
|
||||||
Dictionary<string, DynamicSchemaColumn> Schema { get; }
|
Dictionary<string, DynamicSchemaColumn> Schema { get; }
|
||||||
}
|
}
|
||||||
@@ -8318,12 +8323,14 @@ namespace DynamORM
|
|||||||
/// <param name="name">The name of table.</param>
|
/// <param name="name">The name of table.</param>
|
||||||
/// <param name="alias">The table alias.</param>
|
/// <param name="alias">The table alias.</param>
|
||||||
/// <param name="owner">The table owner.</param>
|
/// <param name="owner">The table owner.</param>
|
||||||
public TableInfo(DynamicDatabase db, string name, string alias = null, string owner = null)
|
/// <param name="nolock">The table should be used with nolock.</param>
|
||||||
|
public TableInfo(DynamicDatabase db, string name, string alias = null, string owner = null, bool nolock = false)
|
||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Alias = alias;
|
Alias = alias;
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
|
NoLock = nolock;
|
||||||
|
|
||||||
if (!name.ContainsAny(StringExtensions.InvalidMemberChars))
|
if (!name.ContainsAny(StringExtensions.InvalidMemberChars))
|
||||||
Schema = db.GetSchema(name, owner: owner);
|
Schema = db.GetSchema(name, owner: owner);
|
||||||
@@ -8336,7 +8343,8 @@ namespace DynamORM
|
|||||||
/// <param name="type">The type which can be mapped to database.</param>
|
/// <param name="type">The type which can be mapped to database.</param>
|
||||||
/// <param name="alias">The table alias.</param>
|
/// <param name="alias">The table alias.</param>
|
||||||
/// <param name="owner">The table owner.</param>
|
/// <param name="owner">The table owner.</param>
|
||||||
public TableInfo(DynamicDatabase db, Type type, string alias = null, string owner = null)
|
/// <param name="nolock">The table should be used with nolock.</param>
|
||||||
|
public TableInfo(DynamicDatabase db, Type type, string alias = null, string owner = null, bool nolock = false)
|
||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(type);
|
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(type);
|
||||||
@@ -8346,6 +8354,7 @@ namespace DynamORM
|
|||||||
|
|
||||||
Owner = (mapper.Table != null) ? mapper.Table.Owner : owner;
|
Owner = (mapper.Table != null) ? mapper.Table.Owner : owner;
|
||||||
Alias = alias;
|
Alias = alias;
|
||||||
|
NoLock = nolock;
|
||||||
|
|
||||||
Schema = db.GetSchema(type);
|
Schema = db.GetSchema(type);
|
||||||
}
|
}
|
||||||
@@ -8359,6 +8368,9 @@ namespace DynamORM
|
|||||||
/// <summary>Gets or sets table alias.</summary>
|
/// <summary>Gets or sets table alias.</summary>
|
||||||
public string Alias { get; internal set; }
|
public string Alias { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>Gets or sets table alias.</summary>
|
||||||
|
public bool NoLock { get; internal set; }
|
||||||
|
|
||||||
/// <summary>Gets or sets table schema.</summary>
|
/// <summary>Gets or sets table schema.</summary>
|
||||||
public Dictionary<string, DynamicSchemaColumn> Schema { get; internal set; }
|
public Dictionary<string, DynamicSchemaColumn> Schema { get; internal set; }
|
||||||
|
|
||||||
@@ -8467,6 +8479,7 @@ namespace DynamORM
|
|||||||
Database.AddToCache(this);
|
Database.AddToCache(this);
|
||||||
|
|
||||||
SupportSchema = (db.Options & DynamicDatabaseOptions.SupportSchema) == DynamicDatabaseOptions.SupportSchema;
|
SupportSchema = (db.Options & DynamicDatabaseOptions.SupportSchema) == DynamicDatabaseOptions.SupportSchema;
|
||||||
|
SupportNoLock = (db.Options & DynamicDatabaseOptions.SupportNoLock) == DynamicDatabaseOptions.SupportNoLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the <see cref="DynamicQueryBuilder"/> class.</summary>
|
/// <summary>Initializes a new instance of the <see cref="DynamicQueryBuilder"/> class.</summary>
|
||||||
@@ -8515,6 +8528,9 @@ namespace DynamORM
|
|||||||
/// <summary>Gets a value indicating whether database supports standard schema.</summary>
|
/// <summary>Gets a value indicating whether database supports standard schema.</summary>
|
||||||
public bool SupportSchema { get; private set; }
|
public bool SupportSchema { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>Gets a value indicating whether database supports with no lock syntax.</summary>
|
||||||
|
public bool SupportNoLock { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates the text this command will execute against the underlying database.
|
/// Generates the text this command will execute against the underlying database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -8957,6 +8973,15 @@ namespace DynamORM
|
|||||||
item = item.Validated("Alias"); // Intercepting null and empty aliases
|
item = item.Validated("Alias"); // Intercepting null and empty aliases
|
||||||
return string.Format("{0} AS {1}", parent, item);
|
return string.Format("{0} AS {1}", parent, item);
|
||||||
|
|
||||||
|
case "NOLOCK":
|
||||||
|
if (!SupportNoLock)
|
||||||
|
return parent;
|
||||||
|
|
||||||
|
if (node.Arguments != null && node.Arguments.Length > 1)
|
||||||
|
throw new ArgumentException("NOLOCK method expects no arguments.");
|
||||||
|
|
||||||
|
return string.Format("{0} {1}", parent, "WITH(NOLOCK)");
|
||||||
|
|
||||||
case "COUNT":
|
case "COUNT":
|
||||||
if (node.Arguments != null && node.Arguments.Length > 1)
|
if (node.Arguments != null && node.Arguments.Length > 1)
|
||||||
throw new ArgumentException("COUNT method expects one or none argument: " + node.Arguments.Sketch());
|
throw new ArgumentException("COUNT method expects one or none argument: " + node.Arguments.Sketch());
|
||||||
@@ -9512,6 +9537,7 @@ namespace DynamORM
|
|||||||
string owner = null;
|
string owner = null;
|
||||||
string main = null;
|
string main = null;
|
||||||
string alias = null;
|
string alias = null;
|
||||||
|
bool nolock = false;
|
||||||
Type type = null;
|
Type type = null;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@@ -9536,6 +9562,20 @@ namespace DynamORM
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Support for the NoLock() virtual method...
|
||||||
|
if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "NOLOCK")
|
||||||
|
{
|
||||||
|
object[] args = ((DynamicParser.Node.Method)node).Arguments;
|
||||||
|
|
||||||
|
if (args != null && args.Length > 0)
|
||||||
|
throw new ArgumentNullException("arg", "NoLock() doesn't support arguments.");
|
||||||
|
|
||||||
|
nolock = true;
|
||||||
|
|
||||||
|
node = node.Host;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "subquery")
|
/*if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "subquery")
|
||||||
{
|
{
|
||||||
main = Parse(this.SubQuery(((DynamicParser.Node.Method)node).Arguments.Where(p => p is Func<dynamic, object>).Cast<Func<dynamic, object>>().ToArray()), Parameters);
|
main = Parse(this.SubQuery(((DynamicParser.Node.Method)node).Arguments.Where(p => p is Func<dynamic, object>).Cast<Func<dynamic, object>>().ToArray()), Parameters);
|
||||||
@@ -9605,7 +9645,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(main))
|
if (!string.IsNullOrEmpty(main))
|
||||||
tableInfo = type == null ? new TableInfo(Database, main, alias, owner) : new TableInfo(Database, type, alias, owner);
|
tableInfo = type == null ? new TableInfo(Database, main, alias, owner, nolock) : new TableInfo(Database, type, alias, owner, nolock);
|
||||||
else
|
else
|
||||||
throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
|
throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
|
||||||
}
|
}
|
||||||
@@ -9627,6 +9667,9 @@ namespace DynamORM
|
|||||||
if (!string.IsNullOrEmpty(tableInfo.Alias))
|
if (!string.IsNullOrEmpty(tableInfo.Alias))
|
||||||
sb.AppendFormat(" AS {0}", tableInfo.Alias);
|
sb.AppendFormat(" AS {0}", tableInfo.Alias);
|
||||||
|
|
||||||
|
if (SupportNoLock && tableInfo.NoLock)
|
||||||
|
sb.AppendFormat(" WITH(NOLOCK)");
|
||||||
|
|
||||||
_from = string.IsNullOrEmpty(_from) ? sb.ToString() : string.Format("{0}, {1}", _from, sb.ToString());
|
_from = string.IsNullOrEmpty(_from) ? sb.ToString() : string.Format("{0}, {1}", _from, sb.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9696,6 +9739,7 @@ namespace DynamORM
|
|||||||
string owner = null;
|
string owner = null;
|
||||||
string alias = null;
|
string alias = null;
|
||||||
string condition = null;
|
string condition = null;
|
||||||
|
bool nolock = false;
|
||||||
Type tableType = null;
|
Type tableType = null;
|
||||||
|
|
||||||
// If the expression resolves to a string...
|
// If the expression resolves to a string...
|
||||||
@@ -9773,6 +9817,20 @@ namespace DynamORM
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Support for the NoLock() virtual method...
|
||||||
|
if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "NOLOCK")
|
||||||
|
{
|
||||||
|
object[] args = ((DynamicParser.Node.Method)node).Arguments;
|
||||||
|
|
||||||
|
if (args != null && args.Length > 0)
|
||||||
|
throw new ArgumentNullException("arg", "NoLock() doesn't support arguments.");
|
||||||
|
|
||||||
|
nolock = true;
|
||||||
|
|
||||||
|
node = node.Host;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Support for table specifications...
|
// Support for table specifications...
|
||||||
if (node is DynamicParser.Node.GetMember)
|
if (node is DynamicParser.Node.GetMember)
|
||||||
{
|
{
|
||||||
@@ -9884,7 +9942,7 @@ namespace DynamORM
|
|||||||
if (justAddTables)
|
if (justAddTables)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(main))
|
if (!string.IsNullOrEmpty(main))
|
||||||
tableInfo = tableType == null ? new TableInfo(Database, main, alias, owner) : new TableInfo(Database, tableType, alias, owner);
|
tableInfo = tableType == null ? new TableInfo(Database, main, alias, owner, nolock) : new TableInfo(Database, tableType, alias, owner, nolock);
|
||||||
else
|
else
|
||||||
throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
|
throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
|
||||||
|
|
||||||
@@ -9912,6 +9970,9 @@ namespace DynamORM
|
|||||||
if (!string.IsNullOrEmpty(tableInfo.Alias))
|
if (!string.IsNullOrEmpty(tableInfo.Alias))
|
||||||
sb.AppendFormat(" AS {0}", tableInfo.Alias);
|
sb.AppendFormat(" AS {0}", tableInfo.Alias);
|
||||||
|
|
||||||
|
if (SupportNoLock && tableInfo.NoLock)
|
||||||
|
sb.AppendFormat(" WITH(NOLOCK)");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(condition))
|
if (!string.IsNullOrEmpty(condition))
|
||||||
sb.AppendFormat(" ON {0}", condition);
|
sb.AppendFormat(" ON {0}", condition);
|
||||||
|
|
||||||
@@ -14510,7 +14571,8 @@ namespace DynamORM
|
|||||||
/// <returns>Objects enumerator.</returns>
|
/// <returns>Objects enumerator.</returns>
|
||||||
public virtual IEnumerable<T> GetAll()
|
public virtual IEnumerable<T> GetAll()
|
||||||
{
|
{
|
||||||
return EnumerateQuery(_database.From<T>());
|
using (var q = _database.From<T>())
|
||||||
|
return EnumerateQuery(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Get rows from database by custom query.</summary>
|
/// <summary>Get rows from database by custom query.</summary>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace AmalgamationTool
|
|||||||
|
|
||||||
// Deal with usings
|
// Deal with usings
|
||||||
foreach (var u in content.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)
|
foreach (var u in content.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)
|
||||||
.Where(l => l.Trim().StartsWith("using "))
|
.Where(l => l.Trim().StartsWith("using ") && !l.Trim().StartsWith("using ("))
|
||||||
.Select(l => l.Trim()))
|
.Select(l => l.Trim()))
|
||||||
if (!usings.Contains(u))
|
if (!usings.Contains(u))
|
||||||
usings.Add(u);
|
usings.Add(u);
|
||||||
@@ -96,6 +96,41 @@ namespace AmalgamationTool
|
|||||||
|
|
||||||
FillClassesAndNamespacesIddented(classes, sb);
|
FillClassesAndNamespacesIddented(classes, sb);
|
||||||
|
|
||||||
|
string amalgamation = sb.ToString();
|
||||||
|
|
||||||
|
sb = new StringBuilder();
|
||||||
|
|
||||||
|
string prevTrimmed = null;
|
||||||
|
|
||||||
|
string[] array = amalgamation.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
|
||||||
|
|
||||||
|
for (int i = 0; i < array.Length; i++)
|
||||||
|
{
|
||||||
|
string l = array[i];
|
||||||
|
var currentTrimmed = l.Trim();
|
||||||
|
var nextTrimmed = (i + 1 == array.Length) ? null : array[i + 1].Trim();
|
||||||
|
|
||||||
|
if (prevTrimmed != null)
|
||||||
|
{
|
||||||
|
switch (prevTrimmed)
|
||||||
|
{
|
||||||
|
case "":
|
||||||
|
if (currentTrimmed == string.Empty)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "{":
|
||||||
|
case "}":
|
||||||
|
if (currentTrimmed == string.Empty && (nextTrimmed == prevTrimmed || nextTrimmed == string.Empty))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.AppendLine(l);
|
||||||
|
prevTrimmed = currentTrimmed;
|
||||||
|
}
|
||||||
|
|
||||||
File.WriteAllText(Path.GetFullPath(args[1].Trim('"', '\'')), sb.ToString());
|
File.WriteAllText(Path.GetFullPath(args[1].Trim('"', '\'')), sb.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ namespace DynamORM.Tests.Select
|
|||||||
CreateDynamicDatabase(
|
CreateDynamicDatabase(
|
||||||
DynamicDatabaseOptions.SingleConnection |
|
DynamicDatabaseOptions.SingleConnection |
|
||||||
DynamicDatabaseOptions.SingleTransaction |
|
DynamicDatabaseOptions.SingleTransaction |
|
||||||
DynamicDatabaseOptions.SupportLimitOffset);
|
DynamicDatabaseOptions.SupportLimitOffset |
|
||||||
|
DynamicDatabaseOptions.SupportNoLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Tear down test objects.</summary>
|
/// <summary>Tear down test objects.</summary>
|
||||||
@@ -98,6 +99,18 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c", cmd.CommandText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method with as expression in text.
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void TestFromGetAsNoLock1()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As("c").NoLock());
|
||||||
|
Assert.AreEqual("SELECT * FROM \"dbo\".\"Users\" AS c WITH(NOLOCK)", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests from method with as expression using lambda.
|
/// Tests from method with as expression using lambda.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -211,6 +224,19 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual("SELECT * FROM (SELECT * FROM \"dbo\".\"Users\") AS u", cmd.CommandText());
|
Assert.AreEqual("SELECT * FROM (SELECT * FROM \"dbo\".\"Users\") AS u", cmd.CommandText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method using invoke with sub query.
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void TestFromSubQuery4()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u(new DynamicSelectQueryBuilder(Database).From(x => x.dbo.Users.NoLock())).As("u"));
|
||||||
|
|
||||||
|
Assert.AreEqual("SELECT * FROM (SELECT * FROM \"dbo\".\"Users\" WITH(NOLOCK)) AS u", cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests where method with alias.
|
/// Tests where method with alias.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -416,6 +442,35 @@ namespace DynamORM.Tests.Select
|
|||||||
Assert.AreEqual(string.Format("SELECT usr.*, uc.\"Users\" FROM \"dbo\".\"Users\" AS usr INNER JOIN (SELECT * FROM \"dbo\".\"UserClients\" WHERE (\"Deleted\" = [${0}])) AS uc ON ((usr.\"Id_User\" = uc.\"User_Id\") AND (uc.\"Users\" IS NOT NULL))", cmd.Parameters.Keys.First()), cmd.CommandText());
|
Assert.AreEqual(string.Format("SELECT usr.*, uc.\"Users\" FROM \"dbo\".\"Users\" AS usr INNER JOIN (SELECT * FROM \"dbo\".\"UserClients\" WHERE (\"Deleted\" = [${0}])) AS uc ON ((usr.\"Id_User\" = uc.\"User_Id\") AND (uc.\"Users\" IS NOT NULL))", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests from method using invoke with sub query an no lock.
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void TestInnerJoin5()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.usr).NoLock())
|
||||||
|
.SubQuery((b, s) => b.Join(usr => usr(s.From(x => x.dbo.UserClients.NoLock()).Where(x => x.Deleted == 0)).Inner().As(usr.uc).On(usr.Id_User == usr.uc.User_Id && usr.uc.Users != null)))
|
||||||
|
.Select(usr => usr.All(), uc => uc.Users);
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT usr.*, uc.\"Users\" FROM \"dbo\".\"Users\" AS usr WITH(NOLOCK) INNER JOIN (SELECT * FROM \"dbo\".\"UserClients\" WITH(NOLOCK) WHERE (\"Deleted\" = [${0}])) AS uc ON ((usr.\"Id_User\" = uc.\"User_Id\") AND (uc.\"Users\" IS NOT NULL))", cmd.Parameters.Keys.First()), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests inner join method with no lock.
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void TestInnerJoin6()
|
||||||
|
{
|
||||||
|
IDynamicSelectQueryBuilder cmd = new DynamicSelectQueryBuilder(Database);
|
||||||
|
|
||||||
|
cmd.From(u => u.dbo.Users.As(u.usr).NoLock())
|
||||||
|
.Join(u => u.Inner().dbo.UserClients.AS(u.uc).NoLock().On(u.usr.Id_User == u.uc.User_Id));
|
||||||
|
|
||||||
|
Assert.AreEqual(string.Format("SELECT * FROM \"dbo\".\"Users\" AS usr WITH(NOLOCK) INNER JOIN \"dbo\".\"UserClients\" AS uc WITH(NOLOCK) ON (usr.\"Id_User\" = uc.\"User_Id\")"), cmd.CommandText());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests left outer join method.
|
/// Tests left outer join method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ namespace DynamORM.Builders
|
|||||||
/// <summary>Gets table alias.</summary>
|
/// <summary>Gets table alias.</summary>
|
||||||
string Alias { get; }
|
string Alias { get; }
|
||||||
|
|
||||||
|
/// <summary>Gets table no lock status.</summary>
|
||||||
|
bool NoLock { get; }
|
||||||
|
|
||||||
/// <summary>Gets table schema.</summary>
|
/// <summary>Gets table schema.</summary>
|
||||||
Dictionary<string, DynamicSchemaColumn> Schema { get; }
|
Dictionary<string, DynamicSchemaColumn> Schema { get; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,12 +86,14 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <param name="name">The name of table.</param>
|
/// <param name="name">The name of table.</param>
|
||||||
/// <param name="alias">The table alias.</param>
|
/// <param name="alias">The table alias.</param>
|
||||||
/// <param name="owner">The table owner.</param>
|
/// <param name="owner">The table owner.</param>
|
||||||
public TableInfo(DynamicDatabase db, string name, string alias = null, string owner = null)
|
/// <param name="nolock">The table should be used with nolock.</param>
|
||||||
|
public TableInfo(DynamicDatabase db, string name, string alias = null, string owner = null, bool nolock = false)
|
||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Alias = alias;
|
Alias = alias;
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
|
NoLock = nolock;
|
||||||
|
|
||||||
if (!name.ContainsAny(StringExtensions.InvalidMemberChars))
|
if (!name.ContainsAny(StringExtensions.InvalidMemberChars))
|
||||||
Schema = db.GetSchema(name, owner: owner);
|
Schema = db.GetSchema(name, owner: owner);
|
||||||
@@ -104,7 +106,8 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <param name="type">The type which can be mapped to database.</param>
|
/// <param name="type">The type which can be mapped to database.</param>
|
||||||
/// <param name="alias">The table alias.</param>
|
/// <param name="alias">The table alias.</param>
|
||||||
/// <param name="owner">The table owner.</param>
|
/// <param name="owner">The table owner.</param>
|
||||||
public TableInfo(DynamicDatabase db, Type type, string alias = null, string owner = null)
|
/// <param name="nolock">The table should be used with nolock.</param>
|
||||||
|
public TableInfo(DynamicDatabase db, Type type, string alias = null, string owner = null, bool nolock = false)
|
||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(type);
|
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(type);
|
||||||
@@ -114,6 +117,7 @@ namespace DynamORM.Builders.Implementation
|
|||||||
|
|
||||||
Owner = (mapper.Table != null) ? mapper.Table.Owner : owner;
|
Owner = (mapper.Table != null) ? mapper.Table.Owner : owner;
|
||||||
Alias = alias;
|
Alias = alias;
|
||||||
|
NoLock = nolock;
|
||||||
|
|
||||||
Schema = db.GetSchema(type);
|
Schema = db.GetSchema(type);
|
||||||
}
|
}
|
||||||
@@ -127,6 +131,9 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <summary>Gets or sets table alias.</summary>
|
/// <summary>Gets or sets table alias.</summary>
|
||||||
public string Alias { get; internal set; }
|
public string Alias { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>Gets or sets table alias.</summary>
|
||||||
|
public bool NoLock { get; internal set; }
|
||||||
|
|
||||||
/// <summary>Gets or sets table schema.</summary>
|
/// <summary>Gets or sets table schema.</summary>
|
||||||
public Dictionary<string, DynamicSchemaColumn> Schema { get; internal set; }
|
public Dictionary<string, DynamicSchemaColumn> Schema { get; internal set; }
|
||||||
|
|
||||||
@@ -235,6 +242,7 @@ namespace DynamORM.Builders.Implementation
|
|||||||
Database.AddToCache(this);
|
Database.AddToCache(this);
|
||||||
|
|
||||||
SupportSchema = (db.Options & DynamicDatabaseOptions.SupportSchema) == DynamicDatabaseOptions.SupportSchema;
|
SupportSchema = (db.Options & DynamicDatabaseOptions.SupportSchema) == DynamicDatabaseOptions.SupportSchema;
|
||||||
|
SupportNoLock = (db.Options & DynamicDatabaseOptions.SupportNoLock) == DynamicDatabaseOptions.SupportNoLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the <see cref="DynamicQueryBuilder"/> class.</summary>
|
/// <summary>Initializes a new instance of the <see cref="DynamicQueryBuilder"/> class.</summary>
|
||||||
@@ -283,6 +291,9 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <summary>Gets a value indicating whether database supports standard schema.</summary>
|
/// <summary>Gets a value indicating whether database supports standard schema.</summary>
|
||||||
public bool SupportSchema { get; private set; }
|
public bool SupportSchema { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>Gets a value indicating whether database supports with no lock syntax.</summary>
|
||||||
|
public bool SupportNoLock { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates the text this command will execute against the underlying database.
|
/// Generates the text this command will execute against the underlying database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -725,6 +736,15 @@ namespace DynamORM.Builders.Implementation
|
|||||||
item = item.Validated("Alias"); // Intercepting null and empty aliases
|
item = item.Validated("Alias"); // Intercepting null and empty aliases
|
||||||
return string.Format("{0} AS {1}", parent, item);
|
return string.Format("{0} AS {1}", parent, item);
|
||||||
|
|
||||||
|
case "NOLOCK":
|
||||||
|
if (!SupportNoLock)
|
||||||
|
return parent;
|
||||||
|
|
||||||
|
if (node.Arguments != null && node.Arguments.Length > 1)
|
||||||
|
throw new ArgumentException("NOLOCK method expects no arguments.");
|
||||||
|
|
||||||
|
return string.Format("{0} {1}", parent, "WITH(NOLOCK)");
|
||||||
|
|
||||||
case "COUNT":
|
case "COUNT":
|
||||||
if (node.Arguments != null && node.Arguments.Length > 1)
|
if (node.Arguments != null && node.Arguments.Length > 1)
|
||||||
throw new ArgumentException("COUNT method expects one or none argument: " + node.Arguments.Sketch());
|
throw new ArgumentException("COUNT method expects one or none argument: " + node.Arguments.Sketch());
|
||||||
|
|||||||
@@ -346,6 +346,7 @@ namespace DynamORM.Builders.Implementation
|
|||||||
string owner = null;
|
string owner = null;
|
||||||
string main = null;
|
string main = null;
|
||||||
string alias = null;
|
string alias = null;
|
||||||
|
bool nolock = false;
|
||||||
Type type = null;
|
Type type = null;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@@ -370,6 +371,20 @@ namespace DynamORM.Builders.Implementation
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Support for the NoLock() virtual method...
|
||||||
|
if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "NOLOCK")
|
||||||
|
{
|
||||||
|
object[] args = ((DynamicParser.Node.Method)node).Arguments;
|
||||||
|
|
||||||
|
if (args != null && args.Length > 0)
|
||||||
|
throw new ArgumentNullException("arg", "NoLock() doesn't support arguments.");
|
||||||
|
|
||||||
|
nolock = true;
|
||||||
|
|
||||||
|
node = node.Host;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "subquery")
|
/*if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "subquery")
|
||||||
{
|
{
|
||||||
main = Parse(this.SubQuery(((DynamicParser.Node.Method)node).Arguments.Where(p => p is Func<dynamic, object>).Cast<Func<dynamic, object>>().ToArray()), Parameters);
|
main = Parse(this.SubQuery(((DynamicParser.Node.Method)node).Arguments.Where(p => p is Func<dynamic, object>).Cast<Func<dynamic, object>>().ToArray()), Parameters);
|
||||||
@@ -439,7 +454,7 @@ namespace DynamORM.Builders.Implementation
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(main))
|
if (!string.IsNullOrEmpty(main))
|
||||||
tableInfo = type == null ? new TableInfo(Database, main, alias, owner) : new TableInfo(Database, type, alias, owner);
|
tableInfo = type == null ? new TableInfo(Database, main, alias, owner, nolock) : new TableInfo(Database, type, alias, owner, nolock);
|
||||||
else
|
else
|
||||||
throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
|
throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
|
||||||
}
|
}
|
||||||
@@ -461,6 +476,9 @@ namespace DynamORM.Builders.Implementation
|
|||||||
if (!string.IsNullOrEmpty(tableInfo.Alias))
|
if (!string.IsNullOrEmpty(tableInfo.Alias))
|
||||||
sb.AppendFormat(" AS {0}", tableInfo.Alias);
|
sb.AppendFormat(" AS {0}", tableInfo.Alias);
|
||||||
|
|
||||||
|
if (SupportNoLock && tableInfo.NoLock)
|
||||||
|
sb.AppendFormat(" WITH(NOLOCK)");
|
||||||
|
|
||||||
_from = string.IsNullOrEmpty(_from) ? sb.ToString() : string.Format("{0}, {1}", _from, sb.ToString());
|
_from = string.IsNullOrEmpty(_from) ? sb.ToString() : string.Format("{0}, {1}", _from, sb.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,6 +548,7 @@ namespace DynamORM.Builders.Implementation
|
|||||||
string owner = null;
|
string owner = null;
|
||||||
string alias = null;
|
string alias = null;
|
||||||
string condition = null;
|
string condition = null;
|
||||||
|
bool nolock = false;
|
||||||
Type tableType = null;
|
Type tableType = null;
|
||||||
|
|
||||||
// If the expression resolves to a string...
|
// If the expression resolves to a string...
|
||||||
@@ -607,6 +626,20 @@ namespace DynamORM.Builders.Implementation
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Support for the NoLock() virtual method...
|
||||||
|
if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "NOLOCK")
|
||||||
|
{
|
||||||
|
object[] args = ((DynamicParser.Node.Method)node).Arguments;
|
||||||
|
|
||||||
|
if (args != null && args.Length > 0)
|
||||||
|
throw new ArgumentNullException("arg", "NoLock() doesn't support arguments.");
|
||||||
|
|
||||||
|
nolock = true;
|
||||||
|
|
||||||
|
node = node.Host;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Support for table specifications...
|
// Support for table specifications...
|
||||||
if (node is DynamicParser.Node.GetMember)
|
if (node is DynamicParser.Node.GetMember)
|
||||||
{
|
{
|
||||||
@@ -718,7 +751,7 @@ namespace DynamORM.Builders.Implementation
|
|||||||
if (justAddTables)
|
if (justAddTables)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(main))
|
if (!string.IsNullOrEmpty(main))
|
||||||
tableInfo = tableType == null ? new TableInfo(Database, main, alias, owner) : new TableInfo(Database, tableType, alias, owner);
|
tableInfo = tableType == null ? new TableInfo(Database, main, alias, owner, nolock) : new TableInfo(Database, tableType, alias, owner, nolock);
|
||||||
else
|
else
|
||||||
throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
|
throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
|
||||||
|
|
||||||
@@ -746,6 +779,9 @@ namespace DynamORM.Builders.Implementation
|
|||||||
if (!string.IsNullOrEmpty(tableInfo.Alias))
|
if (!string.IsNullOrEmpty(tableInfo.Alias))
|
||||||
sb.AppendFormat(" AS {0}", tableInfo.Alias);
|
sb.AppendFormat(" AS {0}", tableInfo.Alias);
|
||||||
|
|
||||||
|
if (SupportNoLock && tableInfo.NoLock)
|
||||||
|
sb.AppendFormat(" WITH(NOLOCK)");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(condition))
|
if (!string.IsNullOrEmpty(condition))
|
||||||
sb.AppendFormat(" ON {0}", condition);
|
sb.AppendFormat(" ON {0}", condition);
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ namespace DynamORM
|
|||||||
/// <summary>Database support stored procedures (EXEC procedure ...).</summary>
|
/// <summary>Database support stored procedures (EXEC procedure ...).</summary>
|
||||||
SupportStoredProcedures = 0x00000100,
|
SupportStoredProcedures = 0x00000100,
|
||||||
|
|
||||||
|
/// <summary>Database support with no lock syntax.</summary>
|
||||||
|
SupportNoLock = 0x00001000,
|
||||||
|
|
||||||
/// <summary>Debug option allowing to enable command dumps by default.</summary>
|
/// <summary>Debug option allowing to enable command dumps by default.</summary>
|
||||||
DumpCommands = 0x01000000,
|
DumpCommands = 0x01000000,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user