diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Helper.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Helper.cs
index 35d3a786a..0e9392843 100644
--- a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Helper.cs
+++ b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Helper.cs
@@ -476,6 +476,48 @@ public static TypeLevelMappedForStringEnumCompleteTable CreateTypeLevelMappedFor
#endregion
+ #region UnorganizedTable
+
+ ///
+ /// Creates a list of objects.
+ ///
+ /// The number of rows.
+ /// A list of objects.
+ public static List CreateUnorganizedTables(int count)
+ {
+ var tables = new List();
+ for (var i = 0; i < count; i++)
+ {
+ var index = i + 1;
+ tables.Add(new UnorganizedTable
+ {
+ SessionId = Guid.NewGuid(),
+ ColumnDateTime2 = DateTime.UtcNow,
+ ColumnInt = index,
+ ColumnNVarChar = $"NVARCHAR{index}"
+ });
+ }
+ return tables;
+ }
+
+ ///
+ /// Creates an instance of object.
+ ///
+ /// A new created instance of object.
+ public static UnorganizedTable CreateUnorganizedTable()
+ {
+ var random = new Random();
+ return new UnorganizedTable
+ {
+ SessionId = Guid.NewGuid(),
+ ColumnDateTime2 = DateTime.UtcNow,
+ ColumnInt = random.Next(int.MinValue, int.MaxValue),
+ ColumnNVarChar = Guid.NewGuid().ToString()
+ };
+ }
+
+ #endregion
+
#region Dynamics
#region IdentityTable
diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Models/UnorganizedTable.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Models/UnorganizedTable.cs
new file mode 100644
index 000000000..bb4c89220
--- /dev/null
+++ b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Models/UnorganizedTable.cs
@@ -0,0 +1,19 @@
+using RepoDb.Attributes;
+using System;
+
+namespace RepoDb.IntegrationTests.Models
+{
+ [Map("[dbo].[Unorganized Table]")]
+ public class UnorganizedTable
+ {
+ public long Id { get; set; }
+ [Map("Session Id")]
+ public Guid SessionId { get; set; }
+ [Map("Column Int")]
+ public int? ColumnInt { get; set; }
+ [Map("Column/NVarChar")]
+ public string ColumnNVarChar { get; set; }
+ [Map("Column.DateTime")]
+ public DateTime? ColumnDateTime2 { get; set; }
+ }
+}
diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/ObjectQuotationTest.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/ObjectQuotationTest.cs
new file mode 100644
index 000000000..0b216dde2
--- /dev/null
+++ b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/ObjectQuotationTest.cs
@@ -0,0 +1,315 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using RepoDb.IntegrationTests.Models;
+using RepoDb.IntegrationTests.Setup;
+using System;
+using System.Data.SqlClient;
+using System.Linq;
+
+namespace RepoDb.IntegrationTests
+{
+ [TestClass]
+ public class ObjectQuotationTest
+ {
+ [TestInitialize]
+ public void Initialize()
+ {
+ Database.Initialize();
+ Cleanup();
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ Database.Cleanup();
+ }
+
+ #region Delete
+
+ [TestMethod]
+ public void TestDeleteObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+ var last = entities.Last();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+ var deleteResult = connection.Delete(last.Id);
+
+ // Assert
+ Assert.AreEqual(1, deleteResult);
+ }
+ }
+
+ [TestMethod]
+ public void TestDeleteObjectQuotationViaNonAlphaNumericField()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+ var last = entities.Last();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+ var deleteResult = connection.Delete(e => e.SessionId == last.SessionId);
+
+ // Assert
+ Assert.AreEqual(1, deleteResult);
+ }
+ }
+
+ #endregion
+
+ #region Insert
+
+ [TestMethod]
+ public void TestInsertObjectQuotation()
+ {
+ // Setup
+ var entity = Helper.CreateUnorganizedTable();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var id = connection.Insert(entity);
+
+ // Assert
+ Assert.IsNotNull(id);
+ Assert.IsTrue(id > 0);
+ Assert.AreEqual(1, connection.CountAll());
+ }
+ }
+
+ #endregion
+
+ #region InsertAll
+
+ [TestMethod]
+ public void TestInsertAllObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+
+ // Assert
+ Assert.AreEqual(entities.Count, rowsInserted);
+ Assert.AreEqual(entities.Count, connection.CountAll());
+ }
+ }
+
+ #endregion
+
+ #region Merge
+
+ [TestMethod]
+ public void TestMergeObjectQuotation()
+ {
+ // Setup
+ var entity = Helper.CreateUnorganizedTable();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var id = connection.Merge(entity);
+
+ // Assert
+ Assert.IsNotNull(id);
+ Assert.IsTrue(id > 0);
+ Assert.AreEqual(1, connection.CountAll());
+
+ // Setup
+ entity.ColumnDateTime2 = DateTime.UtcNow;
+ entity.ColumnInt = 2;
+ entity.ColumnNVarChar = Guid.NewGuid().ToString();
+
+ // Act
+ id = connection.Merge(entity);
+ var queryResult = connection.Query(id).First();
+
+ // Assert
+ Helper.AssertPropertiesEquality(entity, queryResult);
+ }
+ }
+
+ #endregion
+
+ #region MergeAll
+
+ [TestMethod]
+ public void TestMergeAllObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsAffected = connection.MergeAll(entities);
+
+ // Assert
+ Assert.AreEqual(entities.Count, rowsAffected);
+ Assert.AreEqual(entities.Count, connection.CountAll());
+
+ // Setup
+ entities.ForEach(entity =>
+ {
+ entity.ColumnDateTime2 = DateTime.UtcNow;
+ entity.ColumnInt = 2;
+ entity.ColumnNVarChar = Guid.NewGuid().ToString();
+ });
+
+ // Act
+ rowsAffected = connection.MergeAll(entities);
+
+ // Assert
+ Assert.AreEqual(entities.Count, rowsAffected);
+
+ // Act
+ var queryAllResult = connection.QueryAll();
+
+ // Assert
+ entities.ForEach(entity => Helper.AssertPropertiesEquality(entity, queryAllResult.First(item => item.Id == entity.Id)));
+ }
+ }
+
+ #endregion
+
+ #region Query
+
+ [TestMethod]
+ public void TestQueryObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+ var last = entities.Last();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+ var queryResult = connection.Query(last.Id).FirstOrDefault();
+
+ // Assert
+ Assert.IsNotNull(queryResult);
+ Helper.AssertPropertiesEquality(last, queryResult);
+ }
+ }
+
+ [TestMethod]
+ public void TestQueryObjectQuotationViaNonAlphaNumericField()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+ var last = entities.Last();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+ var queryResult = connection.Query(e => e.SessionId == last.SessionId).FirstOrDefault();
+
+ // Assert
+ Assert.IsNotNull(queryResult);
+ Helper.AssertPropertiesEquality(last, queryResult);
+ }
+ }
+
+ #endregion
+
+ #region QueryAll
+
+ [TestMethod]
+ public void TestQueryAllObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+ var queryAllResult = connection.QueryAll();
+
+ // Assert
+ Assert.AreEqual(entities.Count, queryAllResult.Count());
+ entities.ForEach(entity => Helper.AssertPropertiesEquality(entity, queryAllResult.First(item => item.Id == entity.Id)));
+ }
+ }
+
+ #endregion
+
+ #region Update
+
+ [TestMethod]
+ public void TestUpdateObjectQuotation()
+ {
+ // Setup
+ var entity = Helper.CreateUnorganizedTable();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var id = connection.Insert(entity);
+
+ // Setup
+ entity.ColumnDateTime2 = DateTime.UtcNow;
+ entity.ColumnInt = 2;
+ entity.ColumnNVarChar = Guid.NewGuid().ToString();
+
+ // Act
+ var updateReuslt = connection.Update(entity);
+ var queryResult = connection.Query(id).First();
+
+ // Assert
+ Assert.AreEqual(1, updateReuslt);
+ Helper.AssertPropertiesEquality(entity, queryResult);
+ }
+ }
+
+ #endregion
+
+ #region UpdateAll
+
+ [TestMethod]
+ public void TestUpdateAllObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsAffected = connection.InsertAll(entities);
+
+ // Setup
+ entities.ForEach(entity =>
+ {
+ entity.ColumnDateTime2 = DateTime.UtcNow;
+ entity.ColumnInt = 2;
+ entity.ColumnNVarChar = Guid.NewGuid().ToString();
+ });
+
+ // Act
+ rowsAffected = connection.UpdateAll(entities);
+
+ // Assert
+ Assert.AreEqual(entities.Count, rowsAffected);
+
+ // Act
+ var queryAllResult = connection.QueryAll();
+
+ // Assert
+ entities.ForEach(entity => Helper.AssertPropertiesEquality(entity, queryAllResult.First(item => item.Id == entity.Id)));
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs
index e1aeaebba..96fa858b3 100644
--- a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs
+++ b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs
@@ -85,6 +85,7 @@ public static void CreateTables()
CreateCompleteTable();
CreateIdentityTable();
CreateNonIdentityTable();
+ CreateUnorganizedTable();
}
///
@@ -108,6 +109,7 @@ public static void Cleanup()
connection.Truncate("[dbo].[CompleteTable]");
connection.Truncate("[sc].[IdentityTable]");
connection.Truncate("[dbo].[NonIdentityTable]");
+ connection.Truncate("[dbo].[Unorganized Table]");
}
}
@@ -190,6 +192,28 @@ [Id] ASC
}
}
+ ///
+ /// Creates an unorganized table that has some non-alphanumeric fields. All fields are nullable.
+ ///
+ public static void CreateUnorganizedTable()
+ {
+ var commandText = @"IF (NOT EXISTS(SELECT 1 FROM [sys].[objects] WHERE type = 'U' AND name = 'Unorganized Table'))
+ BEGIN
+ CREATE TABLE [dbo].[Unorganized Table]
+ (
+ [Id] BIGINT NOT NULL IDENTITY(1, 1),
+ [Session Id] UNIQUEIDENTIFIER NOT NULL,
+ [Column Int] INT NULL,
+ [Column/NVarChar] NVARCHAR(128) NULL,
+ [Column.DateTime] DATETIME2(7) NULL
+ ) ON [PRIMARY];
+ END";
+ using (var connection = new SqlConnection(ConnectionStringForRepoDb).EnsureOpen())
+ {
+ connection.ExecuteNonQuery(commandText);
+ }
+ }
+
///
/// Creates a table that has a complete fields. All fields are nullable.
///
diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Others/QuotationTest.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Others/QuotationTest.cs
new file mode 100644
index 000000000..6a23019be
--- /dev/null
+++ b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Others/QuotationTest.cs
@@ -0,0 +1,129 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using RepoDb.Extensions;
+
+namespace RepoDb.UnitTests
+{
+ [TestClass]
+ public class QuotationTest
+ {
+ #region AsQuoted
+
+ [TestMethod]
+ public void TestAsQuoted()
+ {
+ // Setup
+ var text = "Value";
+
+ // Act
+ var actual = text.AsQuoted();
+ var expected = "[Value]";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsQuotedWithSpaces()
+ {
+ // Setup
+ var text = " Field Value ";
+
+ // Act
+ var actual = text.AsQuoted();
+ var expected = "[ Field Value ]";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsQuotedWithSpacesAsTrimmed()
+ {
+ // Setup
+ var text = " Field Value ";
+
+ // Act
+ var actual = text.AsQuoted(true);
+ var expected = "[Field Value]";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsQuotedWithSeparators()
+ {
+ // Setup
+ var text = "Database.Schema.Name";
+
+ // Act
+ var actual = text.AsQuoted(true);
+ var expected = "[Database].[Schema].[Name]";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ #endregion
+
+ #region AsUnQuoted
+
+ [TestMethod]
+ public void TestAsUnquoted()
+ {
+ // Setup
+ var text = "[Value]";
+
+ // Act
+ var actual = text.AsUnquoted();
+ var expected = "Value";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsUnquotedWithSpaces()
+ {
+ // Setup
+ var text = " [Field Value] ";
+
+ // Act
+ var actual = text.AsUnquoted();
+ var expected = " Field Value ";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsUnquotedWithSpacesAsTrimmed()
+ {
+ // Setup
+ var text = " [Field Value] ";
+
+ // Act
+ var actual = text.AsUnquoted(true);
+ var expected = "Field Value";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsUnquotedWithSeparators()
+ {
+ // Setup
+ var text = "[Database].[Schema].[Name]";
+
+ // Act
+ var actual = text.AsUnquoted(true);
+ var expected = "Database.Schema.Name";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ #endregion
+ }
+}
diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupCommonTest.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupCommonTest.cs
index c071fc0f2..d0a5a3cda 100644
--- a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupCommonTest.cs
+++ b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupCommonTest.cs
@@ -5,6 +5,7 @@
namespace RepoDb.UnitTests
{
+ [TestClass]
public partial class QueryGroupTest
{
#region Constructor
@@ -770,5 +771,52 @@ public void TestQueryGroupWithEqualAndInIdenticalFields()
}
#endregion
+
+ #region NonAlphaNumericChars
+
+ [TestMethod]
+ public void TestQueryGroupWithSpace()
+ {
+ // Setup
+ var queryGroup = new QueryGroup(new QueryField("Field 1", Operation.Equal, 1));
+
+ // Act
+ var actual = queryGroup.GetString();
+ var expected = "([Field 1] = @Field_1)";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestQueryGroupWithSpaces()
+ {
+ // Setup
+ var queryGroup = new QueryGroup(new QueryField("Date Of Birth", Operation.Equal, 1));
+
+ // Act
+ var actual = queryGroup.GetString();
+ var expected = "([Date Of Birth] = @Date_Of_Birth)";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+
+ [TestMethod]
+ public void TestQueryGroupWithInvalidChars()
+ {
+ // Setup
+ var queryGroup = new QueryGroup(new QueryField("Date.Of.Birth/BirthDay", Operation.Equal, 1));
+
+ // Act
+ var actual = queryGroup.GetString();
+ var expected = "([Date.Of.Birth/BirthDay] = @Date_Of_Birth_BirthDay)";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ #endregion
}
}
diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupParseDynamicCommonTest.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupParseDynamicCommonTest.cs
index bb6613d63..323aff650 100644
--- a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupParseDynamicCommonTest.cs
+++ b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupParseDynamicCommonTest.cs
@@ -2,7 +2,6 @@
namespace RepoDb.UnitTests
{
- [TestClass]
public partial class QueryGroupTest
{
[TestMethod]
diff --git a/RepoDb.Core/RepoDb/Extensions/FieldExtension.cs b/RepoDb.Core/RepoDb/Extensions/FieldExtension.cs
index aaff364fa..20798810f 100644
--- a/RepoDb.Core/RepoDb/Extensions/FieldExtension.cs
+++ b/RepoDb.Core/RepoDb/Extensions/FieldExtension.cs
@@ -27,8 +27,8 @@ private static string AsField(this Field field)
// AsParameter
private static string AsParameter(this Field field, int index = 0, string prefix = Constant.DefaultParameterPrefix)
{
- return index > 0 ? string.Concat(prefix, field.UnquotedName, "_", index) :
- string.Concat(prefix, field.UnquotedName);
+ return index > 0 ? string.Concat(prefix, field.UnquotedName.AsAlphaNumeric(true), "_", index) :
+ string.Concat(prefix, field.UnquotedName.AsAlphaNumeric(true));
}
// AsAliasField
diff --git a/RepoDb.Core/RepoDb/Extensions/StringExtension.cs b/RepoDb.Core/RepoDb/Extensions/StringExtension.cs
index b1b802b2a..0ced4be83 100644
--- a/RepoDb.Core/RepoDb/Extensions/StringExtension.cs
+++ b/RepoDb.Core/RepoDb/Extensions/StringExtension.cs
@@ -21,20 +21,54 @@ public static string Join(this IEnumerable strings, string separator)
return string.Join(separator, strings);
}
+ ///
+ /// Removes the non-alphanumeric characters.
+ ///
+ /// The string value where the non-alphanumeric characters will be removed.
+ /// The boolean value that indicates whether to trim the string before removing the non-alphanumeric characters.
+ /// The alphanumeric string.
+ internal static string AsAlphaNumeric(this string value, bool trim = false)
+ {
+ if (trim)
+ {
+ value = value.Trim();
+ }
+ return Regex.Replace(value, @"[^a-zA-Z0-9]", "_");
+ }
+
///
/// Removes the database quotes from the string.
///
/// The string value where the database quotes will be removed.
/// The boolean value that indicates whether to trim the string before unquoting.
+ /// The separator in which the quotes will be removed.
/// The quoted string.
- public static string AsUnquoted(this string value, bool trim = false)
+ public static string AsUnquoted(this string value, bool trim = false, string separator = ".")
{
if (trim)
{
value = value.Trim();
}
- var v = value?.IndexOf(".") >= 0 ? value.Split(".".ToCharArray()).Last() : value;
- return Regex.Replace(v, @"[\[\]']+", "");
+
+ if (string.IsNullOrEmpty(separator) || value.IndexOf(separator) < 0)
+ {
+ return value.AsUnquoted();
+ }
+ else
+ {
+ var splitted = value.Split(separator.ToCharArray());
+ return splitted.Select(s => s.AsUnquoted()).Join(separator);
+ }
+ }
+
+ ///
+ /// Remove the quotes from the string.
+ ///
+ /// The string value where the database quotes will be removed.
+ ///
+ private static string AsUnquoted(this string value)
+ {
+ return Regex.Replace(value, @"[\[\]']+", "");
}
///
@@ -42,26 +76,27 @@ public static string AsUnquoted(this string value, bool trim = false)
///
/// The string value where the database quotes will be added.
/// The boolean value that indicates whether to trim the string before quoting.
+ /// The separator in which the quotes will be placed.
/// The quoted string.
- public static string AsQuoted(this string value, bool trim = false)
+ public static string AsQuoted(this string value, bool trim = false, string separator = ".")
{
if (trim)
{
value = value.Trim();
}
- if (value.IndexOf(".") < 0)
+ if (string.IsNullOrEmpty(separator) || value.IndexOf(separator) < 0)
{
return value.AsQuoted();
}
else
{
- var splitted = value.Split(".".ToCharArray());
- return splitted.Select(s => s.AsQuoted()).Join(".");
+ var splitted = value.Split(separator.ToCharArray());
+ return splitted.Select(s => s.AsQuoted()).Join(separator);
}
}
///
- /// Adds a quotes to the string.
+ /// Add the quotes into the string.
///
/// The string value where the database quotes will be added.
///
diff --git a/RepoDb.Core/RepoDb/Field.cs b/RepoDb.Core/RepoDb/Field.cs
index d44454093..102ebab74 100644
--- a/RepoDb.Core/RepoDb/Field.cs
+++ b/RepoDb.Core/RepoDb/Field.cs
@@ -36,7 +36,7 @@ public Field(string name,
}
// Set the name
- Name = name.AsQuoted(true);
+ Name = name.AsQuoted(true, null);
UnquotedName = name.AsUnquoted(true);
// Set the type
diff --git a/RepoDb.Core/RepoDb/Parameter.cs b/RepoDb.Core/RepoDb/Parameter.cs
index ff93203d6..39e54b1ac 100644
--- a/RepoDb.Core/RepoDb/Parameter.cs
+++ b/RepoDb.Core/RepoDb/Parameter.cs
@@ -35,7 +35,7 @@ internal Parameter(string name, object value, bool prependUnderscore)
}
// Set the properties
- Name = name.AsUnquoted(true);
+ Name = name.AsAlphaNumeric(true);
Value = value;
if (prependUnderscore)
{
diff --git a/RepoDb.Core/RepoDb/Reflection/FunctionFactory.cs b/RepoDb.Core/RepoDb/Reflection/FunctionFactory.cs
index 6e95462d7..f41c3accf 100644
--- a/RepoDb.Core/RepoDb/Reflection/FunctionFactory.cs
+++ b/RepoDb.Core/RepoDb/Reflection/FunctionFactory.cs
@@ -510,12 +510,13 @@ public static Action GetDataEntityDbCommandParameterSetterFu
var parameterAssignments = new List();
// Parameter variables
- var parameterVariable = Expression.Variable(typeOfDbParameter, string.Concat("parameter", field.UnquotedName));
+ var parameterName = field.UnquotedName.AsAlphaNumeric();
+ var parameterVariable = Expression.Variable(typeOfDbParameter, string.Concat("parameter", parameterName));
var parameterInstance = Expression.Call(commandParameterExpression, dbCommandCreateParameterMethod);
parameterAssignments.Add(Expression.Assign(parameterVariable, parameterInstance));
// Set the name
- var nameAssignment = Expression.Call(parameterVariable, dbParameterParameterNameSetMethod, Expression.Constant(field.UnquotedName));
+ var nameAssignment = Expression.Call(parameterVariable, dbParameterParameterNameSetMethod, Expression.Constant(parameterName));
parameterAssignments.Add(nameAssignment);
// Property instance
@@ -616,7 +617,7 @@ public static Action GetDataEntityDbCommandParameterSetterFu
if (isNullable == true)
{
// Identification of the DBNull
- var valueVariable = Expression.Variable(typeOfObject, string.Concat("valueOf", field.UnquotedName));
+ var valueVariable = Expression.Variable(typeOfObject, string.Concat("valueOf", parameterName));
var valueIsNull = Expression.Equal(valueVariable, Expression.Constant(null));
// Set the propert value
@@ -847,25 +848,26 @@ public static Action GetDataEntityDbCommandParameterSetterFu
var propertyVariable = (ParameterExpression)null;
var propertyInstance = (Expression)null;
var classProperty = (ClassProperty)null;
+ var propertyName = field.UnquotedName;
// Set the proper assignments (property)
if (typeOfEntity == typeOfObject)
{
- propertyVariable = Expression.Variable(typeOfPropertyInfo, string.Concat("property", field.UnquotedName));
+ propertyVariable = Expression.Variable(typeOfPropertyInfo, string.Concat("property", propertyName));
propertyInstance = Expression.Call(Expression.Call(instanceVariable, objectGetTypeMethod),
typeGetPropertyMethod,
new[]
{
- Expression.Constant(field.UnquotedName),
+ Expression.Constant(propertyName),
Expression.Constant(BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase)
});
}
else
{
- classProperty = entityProperties.First(property => property.GetUnquotedMappedName().ToLower() == field.UnquotedName.ToLower());
+ classProperty = entityProperties.First(property => property.GetUnquotedMappedName().ToLower() == propertyName.ToLower());
if (classProperty != null)
{
- propertyVariable = Expression.Variable(classProperty.PropertyInfo.PropertyType, string.Concat("property", field.UnquotedName));
+ propertyVariable = Expression.Variable(classProperty.PropertyInfo.PropertyType, string.Concat("property", propertyName));
propertyInstance = Expression.Property(instanceVariable, classProperty.PropertyInfo);
}
}
@@ -998,13 +1000,14 @@ public static Action> GetDataEntitiesDbCommandParamete
var parameterAssignments = new List();
// Parameter variables
- var parameterVariable = Expression.Variable(typeOfDbParameter, string.Concat("parameter", field.UnquotedName));
+ var parameterName = field.UnquotedName.AsAlphaNumeric();
+ var parameterVariable = Expression.Variable(typeOfDbParameter, string.Concat("parameter", parameterName));
var parameterInstance = Expression.Call(commandParameterExpression, dbCommandCreateParameterMethod);
parameterAssignments.Add(Expression.Assign(parameterVariable, parameterInstance));
// Set the name
var nameAssignment = Expression.Call(parameterVariable, dbParameterParameterNameSetMethod,
- Expression.Constant(entityIndex > 0 ? string.Concat(field.UnquotedName, "_", entityIndex) : field.UnquotedName));
+ Expression.Constant(entityIndex > 0 ? string.Concat(parameterName, "_", entityIndex) : parameterName));
parameterAssignments.Add(nameAssignment);
// Property instance
@@ -1105,7 +1108,7 @@ public static Action> GetDataEntitiesDbCommandParamete
if (isNullable == true)
{
// Identification of the DBNull
- var valueVariable = Expression.Variable(typeOfObject, string.Concat("valueOf", field.UnquotedName));
+ var valueVariable = Expression.Variable(typeOfObject, string.Concat("valueOf", parameterName));
var valueIsNull = Expression.Equal(valueVariable, Expression.Constant(null));
// Set the propert value
@@ -1340,25 +1343,26 @@ public static Action> GetDataEntitiesDbCommandParamete
var propertyVariable = (ParameterExpression)null;
var propertyInstance = (Expression)null;
var classProperty = (ClassProperty)null;
+ var propertyName = field.UnquotedName;
// Set the proper assignments (property)
if (typeOfEntity == typeOfObject)
{
- propertyVariable = Expression.Variable(typeOfPropertyInfo, string.Concat("property", field.UnquotedName));
+ propertyVariable = Expression.Variable(typeOfPropertyInfo, string.Concat("property", propertyName));
propertyInstance = Expression.Call(Expression.Call(instanceVariable, objectGetTypeMethod),
typeGetPropertyMethod,
new[]
{
- Expression.Constant(field.UnquotedName),
+ Expression.Constant(propertyName),
Expression.Constant(BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase)
});
}
else
{
- classProperty = entityProperties.FirstOrDefault(property => property.GetUnquotedMappedName().ToLower() == field.UnquotedName.ToLower());
+ classProperty = entityProperties.FirstOrDefault(property => property.GetUnquotedMappedName().ToLower() == propertyName.ToLower());
if (classProperty != null)
{
- propertyVariable = Expression.Variable(classProperty.PropertyInfo.PropertyType, string.Concat("property", field.UnquotedName));
+ propertyVariable = Expression.Variable(classProperty.PropertyInfo.PropertyType, string.Concat("property", propertyName));
propertyInstance = Expression.Property(instanceVariable, classProperty.PropertyInfo);
}
}
@@ -1445,10 +1449,11 @@ public static Action GetDataEntityPropertySetterFromDbComman
var dbParameterValueProperty = typeOfDbParameter.GetProperty("Value");
// Get the entity property
- var property = typeOfEntity.GetProperty(field.UnquotedName).SetMethod;
+ var propertyName = field.UnquotedName.AsAlphaNumeric();
+ var property = typeOfEntity.GetProperty(propertyName).SetMethod;
// Get the command parameter
- var name = parameterName ?? field.UnquotedName;
+ var name = parameterName ?? propertyName;
var parameters = Expression.Property(dbCommandParameterExpression, dbCommandParametersProperty);
var parameter = Expression.Call(parameters, dbParameterCollectionIndexerMethod,
Expression.Constant(index > 0 ? string.Concat(name, "_", index) : name));
@@ -1526,9 +1531,10 @@ internal static void CreateDbCommandParametersFromFields(DbCommand command,
{
// Create the parameter
var parameter = command.CreateParameter();
+ var name = field.UnquotedName.AsAlphaNumeric();
// Set the property
- parameter.ParameterName = index > 0 ? string.Concat(field.UnquotedName, "_", index) : field.UnquotedName;
+ parameter.ParameterName = index > 0 ? string.Concat(name, "_", index) : name;
// Set the Direction
parameter.Direction = direction;
diff --git a/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Helper.cs b/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Helper.cs
index 35d3a786a..0e9392843 100644
--- a/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Helper.cs
+++ b/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Helper.cs
@@ -476,6 +476,48 @@ public static TypeLevelMappedForStringEnumCompleteTable CreateTypeLevelMappedFor
#endregion
+ #region UnorganizedTable
+
+ ///
+ /// Creates a list of objects.
+ ///
+ /// The number of rows.
+ /// A list of objects.
+ public static List CreateUnorganizedTables(int count)
+ {
+ var tables = new List();
+ for (var i = 0; i < count; i++)
+ {
+ var index = i + 1;
+ tables.Add(new UnorganizedTable
+ {
+ SessionId = Guid.NewGuid(),
+ ColumnDateTime2 = DateTime.UtcNow,
+ ColumnInt = index,
+ ColumnNVarChar = $"NVARCHAR{index}"
+ });
+ }
+ return tables;
+ }
+
+ ///
+ /// Creates an instance of object.
+ ///
+ /// A new created instance of object.
+ public static UnorganizedTable CreateUnorganizedTable()
+ {
+ var random = new Random();
+ return new UnorganizedTable
+ {
+ SessionId = Guid.NewGuid(),
+ ColumnDateTime2 = DateTime.UtcNow,
+ ColumnInt = random.Next(int.MinValue, int.MaxValue),
+ ColumnNVarChar = Guid.NewGuid().ToString()
+ };
+ }
+
+ #endregion
+
#region Dynamics
#region IdentityTable
diff --git a/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Models/UnorganizedTable.cs b/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Models/UnorganizedTable.cs
new file mode 100644
index 000000000..bb4c89220
--- /dev/null
+++ b/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Models/UnorganizedTable.cs
@@ -0,0 +1,19 @@
+using RepoDb.Attributes;
+using System;
+
+namespace RepoDb.IntegrationTests.Models
+{
+ [Map("[dbo].[Unorganized Table]")]
+ public class UnorganizedTable
+ {
+ public long Id { get; set; }
+ [Map("Session Id")]
+ public Guid SessionId { get; set; }
+ [Map("Column Int")]
+ public int? ColumnInt { get; set; }
+ [Map("Column/NVarChar")]
+ public string ColumnNVarChar { get; set; }
+ [Map("Column.DateTime")]
+ public DateTime? ColumnDateTime2 { get; set; }
+ }
+}
diff --git a/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/ObjectQuotationTest.cs b/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/ObjectQuotationTest.cs
new file mode 100644
index 000000000..0b216dde2
--- /dev/null
+++ b/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/ObjectQuotationTest.cs
@@ -0,0 +1,315 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using RepoDb.IntegrationTests.Models;
+using RepoDb.IntegrationTests.Setup;
+using System;
+using System.Data.SqlClient;
+using System.Linq;
+
+namespace RepoDb.IntegrationTests
+{
+ [TestClass]
+ public class ObjectQuotationTest
+ {
+ [TestInitialize]
+ public void Initialize()
+ {
+ Database.Initialize();
+ Cleanup();
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ Database.Cleanup();
+ }
+
+ #region Delete
+
+ [TestMethod]
+ public void TestDeleteObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+ var last = entities.Last();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+ var deleteResult = connection.Delete(last.Id);
+
+ // Assert
+ Assert.AreEqual(1, deleteResult);
+ }
+ }
+
+ [TestMethod]
+ public void TestDeleteObjectQuotationViaNonAlphaNumericField()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+ var last = entities.Last();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+ var deleteResult = connection.Delete(e => e.SessionId == last.SessionId);
+
+ // Assert
+ Assert.AreEqual(1, deleteResult);
+ }
+ }
+
+ #endregion
+
+ #region Insert
+
+ [TestMethod]
+ public void TestInsertObjectQuotation()
+ {
+ // Setup
+ var entity = Helper.CreateUnorganizedTable();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var id = connection.Insert(entity);
+
+ // Assert
+ Assert.IsNotNull(id);
+ Assert.IsTrue(id > 0);
+ Assert.AreEqual(1, connection.CountAll());
+ }
+ }
+
+ #endregion
+
+ #region InsertAll
+
+ [TestMethod]
+ public void TestInsertAllObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+
+ // Assert
+ Assert.AreEqual(entities.Count, rowsInserted);
+ Assert.AreEqual(entities.Count, connection.CountAll());
+ }
+ }
+
+ #endregion
+
+ #region Merge
+
+ [TestMethod]
+ public void TestMergeObjectQuotation()
+ {
+ // Setup
+ var entity = Helper.CreateUnorganizedTable();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var id = connection.Merge(entity);
+
+ // Assert
+ Assert.IsNotNull(id);
+ Assert.IsTrue(id > 0);
+ Assert.AreEqual(1, connection.CountAll());
+
+ // Setup
+ entity.ColumnDateTime2 = DateTime.UtcNow;
+ entity.ColumnInt = 2;
+ entity.ColumnNVarChar = Guid.NewGuid().ToString();
+
+ // Act
+ id = connection.Merge(entity);
+ var queryResult = connection.Query(id).First();
+
+ // Assert
+ Helper.AssertPropertiesEquality(entity, queryResult);
+ }
+ }
+
+ #endregion
+
+ #region MergeAll
+
+ [TestMethod]
+ public void TestMergeAllObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsAffected = connection.MergeAll(entities);
+
+ // Assert
+ Assert.AreEqual(entities.Count, rowsAffected);
+ Assert.AreEqual(entities.Count, connection.CountAll());
+
+ // Setup
+ entities.ForEach(entity =>
+ {
+ entity.ColumnDateTime2 = DateTime.UtcNow;
+ entity.ColumnInt = 2;
+ entity.ColumnNVarChar = Guid.NewGuid().ToString();
+ });
+
+ // Act
+ rowsAffected = connection.MergeAll(entities);
+
+ // Assert
+ Assert.AreEqual(entities.Count, rowsAffected);
+
+ // Act
+ var queryAllResult = connection.QueryAll();
+
+ // Assert
+ entities.ForEach(entity => Helper.AssertPropertiesEquality(entity, queryAllResult.First(item => item.Id == entity.Id)));
+ }
+ }
+
+ #endregion
+
+ #region Query
+
+ [TestMethod]
+ public void TestQueryObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+ var last = entities.Last();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+ var queryResult = connection.Query(last.Id).FirstOrDefault();
+
+ // Assert
+ Assert.IsNotNull(queryResult);
+ Helper.AssertPropertiesEquality(last, queryResult);
+ }
+ }
+
+ [TestMethod]
+ public void TestQueryObjectQuotationViaNonAlphaNumericField()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+ var last = entities.Last();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+ var queryResult = connection.Query(e => e.SessionId == last.SessionId).FirstOrDefault();
+
+ // Assert
+ Assert.IsNotNull(queryResult);
+ Helper.AssertPropertiesEquality(last, queryResult);
+ }
+ }
+
+ #endregion
+
+ #region QueryAll
+
+ [TestMethod]
+ public void TestQueryAllObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsInserted = connection.InsertAll(entities);
+ var queryAllResult = connection.QueryAll();
+
+ // Assert
+ Assert.AreEqual(entities.Count, queryAllResult.Count());
+ entities.ForEach(entity => Helper.AssertPropertiesEquality(entity, queryAllResult.First(item => item.Id == entity.Id)));
+ }
+ }
+
+ #endregion
+
+ #region Update
+
+ [TestMethod]
+ public void TestUpdateObjectQuotation()
+ {
+ // Setup
+ var entity = Helper.CreateUnorganizedTable();
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var id = connection.Insert(entity);
+
+ // Setup
+ entity.ColumnDateTime2 = DateTime.UtcNow;
+ entity.ColumnInt = 2;
+ entity.ColumnNVarChar = Guid.NewGuid().ToString();
+
+ // Act
+ var updateReuslt = connection.Update(entity);
+ var queryResult = connection.Query(id).First();
+
+ // Assert
+ Assert.AreEqual(1, updateReuslt);
+ Helper.AssertPropertiesEquality(entity, queryResult);
+ }
+ }
+
+ #endregion
+
+ #region UpdateAll
+
+ [TestMethod]
+ public void TestUpdateAllObjectQuotation()
+ {
+ // Setup
+ var entities = Helper.CreateUnorganizedTables(10);
+
+ using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
+ {
+ // Act
+ var rowsAffected = connection.InsertAll(entities);
+
+ // Setup
+ entities.ForEach(entity =>
+ {
+ entity.ColumnDateTime2 = DateTime.UtcNow;
+ entity.ColumnInt = 2;
+ entity.ColumnNVarChar = Guid.NewGuid().ToString();
+ });
+
+ // Act
+ rowsAffected = connection.UpdateAll(entities);
+
+ // Assert
+ Assert.AreEqual(entities.Count, rowsAffected);
+
+ // Act
+ var queryAllResult = connection.QueryAll();
+
+ // Assert
+ entities.ForEach(entity => Helper.AssertPropertiesEquality(entity, queryAllResult.First(item => item.Id == entity.Id)));
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/RepoDb.IntegrationTests.csproj b/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/RepoDb.IntegrationTests.csproj
index 6f2e07346..4246573ac 100644
--- a/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/RepoDb.IntegrationTests.csproj
+++ b/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/RepoDb.IntegrationTests.csproj
@@ -63,6 +63,7 @@
+
@@ -74,6 +75,7 @@
+
diff --git a/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs b/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs
index e1aeaebba..96fa858b3 100644
--- a/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs
+++ b/RepoDb/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs
@@ -85,6 +85,7 @@ public static void CreateTables()
CreateCompleteTable();
CreateIdentityTable();
CreateNonIdentityTable();
+ CreateUnorganizedTable();
}
///
@@ -108,6 +109,7 @@ public static void Cleanup()
connection.Truncate("[dbo].[CompleteTable]");
connection.Truncate("[sc].[IdentityTable]");
connection.Truncate("[dbo].[NonIdentityTable]");
+ connection.Truncate("[dbo].[Unorganized Table]");
}
}
@@ -190,6 +192,28 @@ [Id] ASC
}
}
+ ///
+ /// Creates an unorganized table that has some non-alphanumeric fields. All fields are nullable.
+ ///
+ public static void CreateUnorganizedTable()
+ {
+ var commandText = @"IF (NOT EXISTS(SELECT 1 FROM [sys].[objects] WHERE type = 'U' AND name = 'Unorganized Table'))
+ BEGIN
+ CREATE TABLE [dbo].[Unorganized Table]
+ (
+ [Id] BIGINT NOT NULL IDENTITY(1, 1),
+ [Session Id] UNIQUEIDENTIFIER NOT NULL,
+ [Column Int] INT NULL,
+ [Column/NVarChar] NVARCHAR(128) NULL,
+ [Column.DateTime] DATETIME2(7) NULL
+ ) ON [PRIMARY];
+ END";
+ using (var connection = new SqlConnection(ConnectionStringForRepoDb).EnsureOpen())
+ {
+ connection.ExecuteNonQuery(commandText);
+ }
+ }
+
///
/// Creates a table that has a complete fields. All fields are nullable.
///
diff --git a/RepoDb/RepoDb.Tests/RepoDb.UnitTests/Others/QuotationTest.cs b/RepoDb/RepoDb.Tests/RepoDb.UnitTests/Others/QuotationTest.cs
new file mode 100644
index 000000000..6a23019be
--- /dev/null
+++ b/RepoDb/RepoDb.Tests/RepoDb.UnitTests/Others/QuotationTest.cs
@@ -0,0 +1,129 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using RepoDb.Extensions;
+
+namespace RepoDb.UnitTests
+{
+ [TestClass]
+ public class QuotationTest
+ {
+ #region AsQuoted
+
+ [TestMethod]
+ public void TestAsQuoted()
+ {
+ // Setup
+ var text = "Value";
+
+ // Act
+ var actual = text.AsQuoted();
+ var expected = "[Value]";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsQuotedWithSpaces()
+ {
+ // Setup
+ var text = " Field Value ";
+
+ // Act
+ var actual = text.AsQuoted();
+ var expected = "[ Field Value ]";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsQuotedWithSpacesAsTrimmed()
+ {
+ // Setup
+ var text = " Field Value ";
+
+ // Act
+ var actual = text.AsQuoted(true);
+ var expected = "[Field Value]";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsQuotedWithSeparators()
+ {
+ // Setup
+ var text = "Database.Schema.Name";
+
+ // Act
+ var actual = text.AsQuoted(true);
+ var expected = "[Database].[Schema].[Name]";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ #endregion
+
+ #region AsUnQuoted
+
+ [TestMethod]
+ public void TestAsUnquoted()
+ {
+ // Setup
+ var text = "[Value]";
+
+ // Act
+ var actual = text.AsUnquoted();
+ var expected = "Value";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsUnquotedWithSpaces()
+ {
+ // Setup
+ var text = " [Field Value] ";
+
+ // Act
+ var actual = text.AsUnquoted();
+ var expected = " Field Value ";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsUnquotedWithSpacesAsTrimmed()
+ {
+ // Setup
+ var text = " [Field Value] ";
+
+ // Act
+ var actual = text.AsUnquoted(true);
+ var expected = "Field Value";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestAsUnquotedWithSeparators()
+ {
+ // Setup
+ var text = "[Database].[Schema].[Name]";
+
+ // Act
+ var actual = text.AsUnquoted(true);
+ var expected = "Database.Schema.Name";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ #endregion
+ }
+}
diff --git a/RepoDb/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupCommonTest.cs b/RepoDb/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupCommonTest.cs
index c071fc0f2..d0a5a3cda 100644
--- a/RepoDb/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupCommonTest.cs
+++ b/RepoDb/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupCommonTest.cs
@@ -5,6 +5,7 @@
namespace RepoDb.UnitTests
{
+ [TestClass]
public partial class QueryGroupTest
{
#region Constructor
@@ -770,5 +771,52 @@ public void TestQueryGroupWithEqualAndInIdenticalFields()
}
#endregion
+
+ #region NonAlphaNumericChars
+
+ [TestMethod]
+ public void TestQueryGroupWithSpace()
+ {
+ // Setup
+ var queryGroup = new QueryGroup(new QueryField("Field 1", Operation.Equal, 1));
+
+ // Act
+ var actual = queryGroup.GetString();
+ var expected = "([Field 1] = @Field_1)";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void TestQueryGroupWithSpaces()
+ {
+ // Setup
+ var queryGroup = new QueryGroup(new QueryField("Date Of Birth", Operation.Equal, 1));
+
+ // Act
+ var actual = queryGroup.GetString();
+ var expected = "([Date Of Birth] = @Date_Of_Birth)";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+
+ [TestMethod]
+ public void TestQueryGroupWithInvalidChars()
+ {
+ // Setup
+ var queryGroup = new QueryGroup(new QueryField("Date.Of.Birth/BirthDay", Operation.Equal, 1));
+
+ // Act
+ var actual = queryGroup.GetString();
+ var expected = "([Date.Of.Birth/BirthDay] = @Date_Of_Birth_BirthDay)";
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ #endregion
}
}
diff --git a/RepoDb/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupParseDynamicCommonTest.cs b/RepoDb/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupParseDynamicCommonTest.cs
index bb6613d63..323aff650 100644
--- a/RepoDb/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupParseDynamicCommonTest.cs
+++ b/RepoDb/RepoDb.Tests/RepoDb.UnitTests/QueryGroups/QueryGroupParseDynamicCommonTest.cs
@@ -2,7 +2,6 @@
namespace RepoDb.UnitTests
{
- [TestClass]
public partial class QueryGroupTest
{
[TestMethod]
diff --git a/RepoDb/RepoDb.Tests/RepoDb.UnitTests/RepoDb.UnitTests.csproj b/RepoDb/RepoDb.Tests/RepoDb.UnitTests/RepoDb.UnitTests.csproj
index 9d0b85bcf..46bfa15fb 100644
--- a/RepoDb/RepoDb.Tests/RepoDb.UnitTests/RepoDb.UnitTests.csproj
+++ b/RepoDb/RepoDb.Tests/RepoDb.UnitTests/RepoDb.UnitTests.csproj
@@ -142,6 +142,7 @@
+
diff --git a/RepoDb/RepoDb/Extensions/FieldExtension.cs b/RepoDb/RepoDb/Extensions/FieldExtension.cs
index aaff364fa..20798810f 100644
--- a/RepoDb/RepoDb/Extensions/FieldExtension.cs
+++ b/RepoDb/RepoDb/Extensions/FieldExtension.cs
@@ -27,8 +27,8 @@ private static string AsField(this Field field)
// AsParameter
private static string AsParameter(this Field field, int index = 0, string prefix = Constant.DefaultParameterPrefix)
{
- return index > 0 ? string.Concat(prefix, field.UnquotedName, "_", index) :
- string.Concat(prefix, field.UnquotedName);
+ return index > 0 ? string.Concat(prefix, field.UnquotedName.AsAlphaNumeric(true), "_", index) :
+ string.Concat(prefix, field.UnquotedName.AsAlphaNumeric(true));
}
// AsAliasField
diff --git a/RepoDb/RepoDb/Extensions/StringExtension.cs b/RepoDb/RepoDb/Extensions/StringExtension.cs
index b1b802b2a..be5cf3d35 100644
--- a/RepoDb/RepoDb/Extensions/StringExtension.cs
+++ b/RepoDb/RepoDb/Extensions/StringExtension.cs
@@ -22,50 +22,61 @@ public static string Join(this IEnumerable strings, string separator)
}
///
- /// Removes the database quotes from the string.
+ /// Removes the non-alphanumeric characters.
///
- /// The string value where the database quotes will be removed.
- /// The boolean value that indicates whether to trim the string before unquoting.
- /// The quoted string.
- public static string AsUnquoted(this string value, bool trim = false)
+ /// The string value where the non-alphanumeric characters will be removed.
+ /// The boolean value that indicates whether to trim the string before removing the non-alphanumeric characters.
+ /// The alphanumeric string.
+ internal static string AsAlphaNumeric(this string value, bool trim = false)
{
if (trim)
{
value = value.Trim();
}
- var v = value?.IndexOf(".") >= 0 ? value.Split(".".ToCharArray()).Last() : value;
- return Regex.Replace(v, @"[\[\]']+", "");
+ return Regex.Replace(value, @"[^a-zA-Z0-9]", "_");
}
///
- /// Adds a quotes to the string.
+ /// Unquotes a string.
///
- /// The string value where the database quotes will be added.
- /// The boolean value that indicates whether to trim the string before quoting.
- /// The quoted string.
- public static string AsQuoted(this string value, bool trim = false)
+ /// The string value to be unqouted.
+ /// The unquoted string.
+ public static string AsUnquoted(this string value)
+ {
+ return Regex.Replace(value, @"[\[\]']+", "");
+ }
+
+ ///
+ /// Unquotes a string.
+ ///
+ /// The string value to be unqouted.
+ /// The boolean value that indicates whether to trim the string before unquoting.
+ /// The separator in which the quotes will be removed.
+ /// The unquoted string.
+ public static string AsUnquoted(this string value, bool trim = false, string separator = ".")
{
if (trim)
{
value = value.Trim();
}
- if (value.IndexOf(".") < 0)
+
+ if (string.IsNullOrEmpty(separator) || value.IndexOf(separator) < 0)
{
- return value.AsQuoted();
+ return value.AsUnquoted();
}
else
{
- var splitted = value.Split(".".ToCharArray());
- return splitted.Select(s => s.AsQuoted()).Join(".");
+ var splitted = value.Split(separator.ToCharArray());
+ return splitted.Select(s => s.AsUnquoted()).Join(separator);
}
}
///
- /// Adds a quotes to the string.
+ /// Quotes a string.
///
- /// The string value where the database quotes will be added.
- ///
- private static string AsQuoted(this string value)
+ /// The string value to be quoted.
+ /// The quoted string.
+ public static string AsQuoted(this string value)
{
if (!value.StartsWith("["))
{
@@ -78,6 +89,30 @@ private static string AsQuoted(this string value)
return value;
}
+ ///
+ /// Quotes a string.
+ ///
+ /// The string value to be quoted.
+ /// The boolean value that indicates whether to trim the string before quoting.
+ /// The separator in which the quotes will be placed.
+ /// The quoted string.
+ public static string AsQuoted(this string value, bool trim = false, string separator = ".")
+ {
+ if (trim)
+ {
+ value = value.Trim();
+ }
+ if (string.IsNullOrEmpty(separator) || value.IndexOf(separator) < 0)
+ {
+ return value.AsQuoted();
+ }
+ else
+ {
+ var splitted = value.Split(separator.ToCharArray());
+ return splitted.Select(s => s.AsQuoted()).Join(separator);
+ }
+ }
+
// AsEnumerable
internal static IEnumerable AsEnumerable(this string value)
{
diff --git a/RepoDb/RepoDb/Field.cs b/RepoDb/RepoDb/Field.cs
index 053a342c4..110aa7310 100644
--- a/RepoDb/RepoDb/Field.cs
+++ b/RepoDb/RepoDb/Field.cs
@@ -35,7 +35,7 @@ public Field(string name,
}
// Set the name
- Name = name.AsQuoted(true);
+ Name = name.AsQuoted(true, null);
UnquotedName = name.AsUnquoted(true);
// Set the type
diff --git a/RepoDb/RepoDb/Parameter.cs b/RepoDb/RepoDb/Parameter.cs
index ff93203d6..39e54b1ac 100644
--- a/RepoDb/RepoDb/Parameter.cs
+++ b/RepoDb/RepoDb/Parameter.cs
@@ -35,7 +35,7 @@ internal Parameter(string name, object value, bool prependUnderscore)
}
// Set the properties
- Name = name.AsUnquoted(true);
+ Name = name.AsAlphaNumeric(true);
Value = value;
if (prependUnderscore)
{
diff --git a/RepoDb/RepoDb/Reflection/FunctionFactory.cs b/RepoDb/RepoDb/Reflection/FunctionFactory.cs
index 6c21235fa..f43a6b901 100644
--- a/RepoDb/RepoDb/Reflection/FunctionFactory.cs
+++ b/RepoDb/RepoDb/Reflection/FunctionFactory.cs
@@ -510,12 +510,13 @@ public static Action GetDataEntityDbCommandParameterSetterFu
var parameterAssignments = new List();
// Parameter variables
- var parameterVariable = Expression.Variable(typeOfDbParameter, string.Concat("parameter", field.UnquotedName));
+ var parameterName = field.UnquotedName.AsAlphaNumeric();
+ var parameterVariable = Expression.Variable(typeOfDbParameter, string.Concat("parameter", parameterName));
var parameterInstance = Expression.Call(commandParameterExpression, dbCommandCreateParameterMethod);
parameterAssignments.Add(Expression.Assign(parameterVariable, parameterInstance));
// Set the name
- var nameAssignment = Expression.Call(parameterVariable, dbParameterParameterNameSetMethod, Expression.Constant(field.UnquotedName));
+ var nameAssignment = Expression.Call(parameterVariable, dbParameterParameterNameSetMethod, Expression.Constant(parameterName));
parameterAssignments.Add(nameAssignment);
// Property instance
@@ -616,7 +617,7 @@ public static Action GetDataEntityDbCommandParameterSetterFu
if (isNullable == true)
{
// Identification of the DBNull
- var valueVariable = Expression.Variable(typeOfObject, string.Concat("valueOf", field.UnquotedName));
+ var valueVariable = Expression.Variable(typeOfObject, string.Concat("valueOf", parameterName));
var valueIsNull = Expression.Equal(valueVariable, Expression.Constant(null));
// Set the propert value
@@ -847,25 +848,26 @@ public static Action GetDataEntityDbCommandParameterSetterFu
var propertyVariable = (ParameterExpression)null;
var propertyInstance = (Expression)null;
var classProperty = (ClassProperty)null;
+ var propertyName = field.UnquotedName;
// Set the proper assignments (property)
if (typeOfEntity == typeOfObject)
{
- propertyVariable = Expression.Variable(typeOfPropertyInfo, string.Concat("property", field.UnquotedName));
+ propertyVariable = Expression.Variable(typeOfPropertyInfo, string.Concat("property", propertyName));
propertyInstance = Expression.Call(Expression.Call(instanceVariable, objectGetTypeMethod),
typeGetPropertyMethod,
new[]
{
- Expression.Constant(field.UnquotedName),
+ Expression.Constant(propertyName),
Expression.Constant(BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase)
});
}
else
{
- classProperty = entityProperties.First(property => property.GetUnquotedMappedName().ToLower() == field.UnquotedName.ToLower());
+ classProperty = entityProperties.First(property => property.GetUnquotedMappedName().ToLower() == propertyName.ToLower());
if (classProperty != null)
{
- propertyVariable = Expression.Variable(classProperty.PropertyInfo.PropertyType, string.Concat("property", field.UnquotedName));
+ propertyVariable = Expression.Variable(classProperty.PropertyInfo.PropertyType, string.Concat("property", propertyName));
propertyInstance = Expression.Property(instanceVariable, classProperty.PropertyInfo);
}
}
@@ -998,13 +1000,14 @@ public static Action> GetDataEntitiesDbCommandParamete
var parameterAssignments = new List();
// Parameter variables
- var parameterVariable = Expression.Variable(typeOfDbParameter, string.Concat("parameter", field.UnquotedName));
+ var parameterName = field.UnquotedName.AsAlphaNumeric();
+ var parameterVariable = Expression.Variable(typeOfDbParameter, string.Concat("parameter", parameterName));
var parameterInstance = Expression.Call(commandParameterExpression, dbCommandCreateParameterMethod);
parameterAssignments.Add(Expression.Assign(parameterVariable, parameterInstance));
// Set the name
var nameAssignment = Expression.Call(parameterVariable, dbParameterParameterNameSetMethod,
- Expression.Constant(entityIndex > 0 ? string.Concat(field.UnquotedName, "_", entityIndex) : field.UnquotedName));
+ Expression.Constant(entityIndex > 0 ? string.Concat(parameterName, "_", entityIndex) : parameterName));
parameterAssignments.Add(nameAssignment);
// Property instance
@@ -1105,7 +1108,7 @@ public static Action> GetDataEntitiesDbCommandParamete
if (isNullable == true)
{
// Identification of the DBNull
- var valueVariable = Expression.Variable(typeOfObject, string.Concat("valueOf", field.UnquotedName));
+ var valueVariable = Expression.Variable(typeOfObject, string.Concat("valueOf", parameterName));
var valueIsNull = Expression.Equal(valueVariable, Expression.Constant(null));
// Set the propert value
@@ -1340,25 +1343,26 @@ public static Action> GetDataEntitiesDbCommandParamete
var propertyVariable = (ParameterExpression)null;
var propertyInstance = (Expression)null;
var classProperty = (ClassProperty)null;
+ var propertyName = field.UnquotedName;
// Set the proper assignments (property)
if (typeOfEntity == typeOfObject)
{
- propertyVariable = Expression.Variable(typeOfPropertyInfo, string.Concat("property", field.UnquotedName));
+ propertyVariable = Expression.Variable(typeOfPropertyInfo, string.Concat("property", propertyName));
propertyInstance = Expression.Call(Expression.Call(instanceVariable, objectGetTypeMethod),
typeGetPropertyMethod,
new[]
{
- Expression.Constant(field.UnquotedName),
+ Expression.Constant(propertyName),
Expression.Constant(BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase)
});
}
else
{
- classProperty = entityProperties.FirstOrDefault(property => property.GetUnquotedMappedName().ToLower() == field.UnquotedName.ToLower());
+ classProperty = entityProperties.FirstOrDefault(property => property.GetUnquotedMappedName().ToLower() == propertyName.ToLower());
if (classProperty != null)
{
- propertyVariable = Expression.Variable(classProperty.PropertyInfo.PropertyType, string.Concat("property", field.UnquotedName));
+ propertyVariable = Expression.Variable(classProperty.PropertyInfo.PropertyType, string.Concat("property", propertyName));
propertyInstance = Expression.Property(instanceVariable, classProperty.PropertyInfo);
}
}
@@ -1445,10 +1449,11 @@ public static Action GetDataEntityPropertySetterFromDbComman
var dbParameterValueProperty = typeOfDbParameter.GetProperty("Value");
// Get the entity property
- var property = typeOfEntity.GetProperty(field.UnquotedName).SetMethod;
+ var propertyName = field.UnquotedName.AsAlphaNumeric();
+ var property = typeOfEntity.GetProperty(propertyName).SetMethod;
// Get the command parameter
- var name = parameterName ?? field.UnquotedName;
+ var name = parameterName ?? propertyName;
var parameters = Expression.Property(dbCommandParameterExpression, dbCommandParametersProperty);
var parameter = Expression.Call(parameters, dbParameterCollectionIndexerMethod,
Expression.Constant(index > 0 ? string.Concat(name, "_", index) : name));
@@ -1526,9 +1531,10 @@ internal static void CreateDbCommandParametersFromFields(DbCommand command,
{
// Create the parameter
var parameter = command.CreateParameter();
+ var name = field.UnquotedName.AsAlphaNumeric();
// Set the property
- parameter.ParameterName = index > 0 ? string.Concat(field.UnquotedName, "_", index) : field.UnquotedName;
+ parameter.ParameterName = index > 0 ? string.Concat(name, "_", index) : name;
// Set the Direction
parameter.Direction = direction;