diff --git a/DynamORM.Tests/Modify/DynamicModificationTests.cs b/DynamORM.Tests/Modify/DynamicModificationTests.cs index 5b9a9af..9411d95 100644 --- a/DynamORM.Tests/Modify/DynamicModificationTests.cs +++ b/DynamORM.Tests/Modify/DynamicModificationTests.cs @@ -26,6 +26,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using DynamORM.Tests.Helpers; using NUnit.Framework; @@ -64,13 +65,13 @@ namespace DynamORM.Tests.Modify [Test] public void TestInsertByArguments() { - Assert.AreEqual(1, GetTestTable().Insert(code: 201, first: "Juri", last: "Gagarin", email: "juri.gagarin@megacorp.com", quote: "bla, bla, bla")); + Assert.AreEqual(1, GetTestTable().Insert(code: 201, first: null, last: "Gagarin", email: "juri.gagarin@megacorp.com", quote: "bla, bla, bla")); // Verify var o = GetTestTable().Single(code: 201); Assert.Less(200, o.id); Assert.AreEqual("201", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); @@ -81,13 +82,13 @@ namespace DynamORM.Tests.Modify [Test] public void TestInsertByDynamicObjects() { - Assert.AreEqual(1, GetTestTable().Insert(values: new { code = 202, first = "Juri", last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" })); + Assert.AreEqual(1, GetTestTable().Insert(values: new { code = 202, first = DBNull.Value, last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" })); // Verify var o = GetTestTable().Single(code: 202); Assert.Less(200, o.id); Assert.AreEqual("202", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); @@ -104,7 +105,7 @@ namespace DynamORM.Tests.Modify { Id = u.Max(columns: "id") + 1, Code = "203", - First = "Juri", + First = null, Last = "Gagarin", Email = "juri.gagarin@megacorp.com", Quote = "bla, bla, bla" @@ -114,7 +115,7 @@ namespace DynamORM.Tests.Modify var o = u.Single(code: 203); Assert.Less(200, o.id); Assert.AreEqual("203", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); @@ -131,7 +132,7 @@ namespace DynamORM.Tests.Modify { id = u.Max(columns: "id") + 1, code = "204", - first = "Juri", + first = null, last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" @@ -141,7 +142,7 @@ namespace DynamORM.Tests.Modify var o = u.Single(code: 204); Assert.Less(200, o.id); Assert.AreEqual("204", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); @@ -156,13 +157,13 @@ namespace DynamORM.Tests.Modify [Test] public void TestUpdateByArguments() { - Assert.AreEqual(1, GetTestTable().Update(id: 1, code: 201, first: "Juri", last: "Gagarin", email: "juri.gagarin@megacorp.com", quote: "bla, bla, bla")); + Assert.AreEqual(1, GetTestTable().Update(id: 1, code: 201, first: null, last: "Gagarin", email: "juri.gagarin@megacorp.com", quote: "bla, bla, bla")); // Verify var o = GetTestTable().Single(code: 201); Assert.AreEqual(1, o.id); Assert.AreEqual("201", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); @@ -173,13 +174,13 @@ namespace DynamORM.Tests.Modify [Test] public void TestUpdateByDynamicObject() { - Assert.AreEqual(1, GetTestTable().Update(update: new { id = 2, code = 202, first = "Juri", last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" })); + Assert.AreEqual(1, GetTestTable().Update(update: new { id = 2, code = 202, first = DBNull.Value, last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" })); // Verify var o = GetTestTable().Single(code: 202); Assert.AreEqual(2, o.id); Assert.AreEqual("202", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); @@ -196,7 +197,7 @@ namespace DynamORM.Tests.Modify { Id = 3, Code = "203", - First = "Juri", + First = null, Last = "Gagarin", Email = "juri.gagarin@megacorp.com", Quote = "bla, bla, bla" @@ -206,7 +207,7 @@ namespace DynamORM.Tests.Modify var o = u.Single(code: 203); Assert.AreEqual(3, o.id); Assert.AreEqual("203", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); @@ -223,7 +224,7 @@ namespace DynamORM.Tests.Modify { id = 4, code = "204", - first = "Juri", + first = null, last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" @@ -233,7 +234,7 @@ namespace DynamORM.Tests.Modify var o = u.Single(code: 204); Assert.AreEqual(4, o.id); Assert.AreEqual("204", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); @@ -244,13 +245,13 @@ namespace DynamORM.Tests.Modify [Test] public void TestUpdateByDynamicObjects() { - Assert.AreEqual(1, GetTestTable().Update(values: new { code = 205, first = "Juri", last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" }, where: new { id = 5 })); + Assert.AreEqual(1, GetTestTable().Update(values: new { code = 205, first = DBNull.Value, last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" }, where: new { id = 5 })); // Verify var o = GetTestTable().Single(code: 205); Assert.AreEqual(5, o.id); Assert.AreEqual("205", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); @@ -267,7 +268,7 @@ namespace DynamORM.Tests.Modify { Id = 6, Code = "206", - First = "Juri", + First = null, Last = "Gagarin", Email = "juri.gagarin@megacorp.com", Quote = "bla, bla, bla" @@ -277,7 +278,7 @@ namespace DynamORM.Tests.Modify var o = u.Single(code: 206); Assert.AreEqual(6, o.id); Assert.AreEqual("206", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); @@ -294,7 +295,7 @@ namespace DynamORM.Tests.Modify { id = 7, code = "207", - first = "Juri", + first = null, last = "Gagarin", email = "juri.gagarin@megacorp.com", quote = "bla, bla, bla" @@ -304,7 +305,7 @@ namespace DynamORM.Tests.Modify var o = u.Single(code: 207); Assert.AreEqual(7, o.id); Assert.AreEqual("207", o.code); - Assert.AreEqual("Juri", o.first); + Assert.AreEqual(null, o.first); Assert.AreEqual("Gagarin", o.last); Assert.AreEqual("juri.gagarin@megacorp.com", o.email); Assert.AreEqual("bla, bla, bla", o.quote); diff --git a/DynamORM/Builders/DynamicInsertQueryBuilder.cs b/DynamORM/Builders/DynamicInsertQueryBuilder.cs index c76e550..79e828f 100644 --- a/DynamORM/Builders/DynamicInsertQueryBuilder.cs +++ b/DynamORM/Builders/DynamicInsertQueryBuilder.cs @@ -37,7 +37,7 @@ namespace DynamORM.Builders /// Insert query builder. public class DynamicInsertQueryBuilder : DynamicQueryBuilder { - /// Gets list of columns that will be seected. + /// Gets list of columns that will be selected. public IDictionary ValueColumns { get; private set; } /// Initializes a new instance of the class. diff --git a/DynamORM/Builders/DynamicSelectQueryBuilder.cs b/DynamORM/Builders/DynamicSelectQueryBuilder.cs index 2bc684b..e977d4d 100644 --- a/DynamORM/Builders/DynamicSelectQueryBuilder.cs +++ b/DynamORM/Builders/DynamicSelectQueryBuilder.cs @@ -37,7 +37,7 @@ namespace DynamORM.Builders /// Select query builder. public class DynamicSelectQueryBuilder : DynamicQueryBuilder { - /// Gets dictionary of columns that will be seected. + /// Gets dictionary of columns that will be selected. public List Columns { get; private set; } /// Gets dictionary of columns that will be used to group query. diff --git a/DynamORM/Builders/DynamicUpdateQueryBuilder.cs b/DynamORM/Builders/DynamicUpdateQueryBuilder.cs index 372b0de..a36fe8a 100644 --- a/DynamORM/Builders/DynamicUpdateQueryBuilder.cs +++ b/DynamORM/Builders/DynamicUpdateQueryBuilder.cs @@ -37,7 +37,7 @@ namespace DynamORM.Builders /// Update query builder. public class DynamicUpdateQueryBuilder : DynamicQueryBuilder { - /// Gets list of columns that will be seected. + /// Gets list of columns that will be selected. public IDictionary ValueColumns { get; private set; } /// Initializes a new instance of the class. diff --git a/DynamORM/DynamicColumn.cs b/DynamORM/DynamicColumn.cs index e87b61d..854122c 100644 --- a/DynamORM/DynamicColumn.cs +++ b/DynamORM/DynamicColumn.cs @@ -71,10 +71,10 @@ namespace DynamORM /// Less or equal operator. Lte, - /// Greather than operator. + /// Greater than operator. Gt, - /// Greather or equal operator. + /// Greater or equal operator. Gte, /// Between two values. @@ -89,7 +89,7 @@ namespace DynamORM public DynamicColumn() { } /// Initializes a new instance of the class. - /// Constructor provided for easier object creation in qeries. + /// Constructor provided for easier object creation in queries. /// Name of column to set. public DynamicColumn(string columnName) : this() @@ -98,7 +98,7 @@ namespace DynamORM } /// Initializes a new instance of the class. - /// Constructor provided for easier object creation in qeries. + /// Constructor provided for easier object creation in queries. /// Name of column to set. /// Compare column to value(s) operator. /// Parameter value(s). @@ -136,18 +136,18 @@ namespace DynamORM /// Gets or sets a value indicating whether this condition will be treated as or condition. public bool Or { get; set; } - /// Gets or sets a value indicating whether start new block in where steatement. + /// Gets or sets a value indicating whether start new block in where statement. public bool BeginBlock { get; set; } - /// Gets or sets a value indicating whether end existing block in where steatement. + /// Gets or sets a value indicating whether end existing block in where statement. public bool EndBlock { get; set; } /// Gets or sets a value indicating whether set parameters for null values. public bool VirtualColumn { get; set; } /// Gets or sets schema representation of a column. - /// Woraround to providers issues which sometimes pass wrong - /// data o schema. For example decimal has precission of 255 in sql + /// Workaround to providers issues which sometimes pass wrong + /// data o schema. For example decimal has precision of 255 in SQL /// server. public DynamicSchemaColumn? Schema { get; set; } @@ -366,7 +366,7 @@ namespace DynamORM } /// Sets the virtual column. - /// If set to true [virt]. + /// Set virtual column value. /// Returns self. public DynamicColumn SetVirtualColumn(bool virt) { diff --git a/DynamORM/DynamicCommand.cs b/DynamORM/DynamicCommand.cs index da4b605..8dcceba 100644 --- a/DynamORM/DynamicCommand.cs +++ b/DynamORM/DynamicCommand.cs @@ -42,7 +42,7 @@ namespace DynamORM /// Initializes a new instance of the class. /// The connection. - /// The databas manager. + /// The database manager. internal DynamicCommand(DynamicConnection con, DynamicDatabase db) { _con = con; @@ -61,8 +61,8 @@ namespace DynamORM } /// Initializes a new instance of the class. - /// The databas manager. - /// Used intenaly to create command without context. + /// The database manager. + /// Used internally to create command without context. internal DynamicCommand(DynamicDatabase db) { _db = db; @@ -177,9 +177,9 @@ namespace DynamORM } /// Executes the query, and returns the first column of the - /// first row in the resultset returned by the query. Extra columns or + /// first row in the result set returned by the query. Extra columns or /// rows are ignored. - /// The first column of the first row in the resultset. + /// The first column of the first row in the result set. public object ExecuteScalar() { return PrepareForExecution().ExecuteScalar(); diff --git a/DynamORM/DynamicConnection.cs b/DynamORM/DynamicConnection.cs index 00ae93c..e7aba2e 100644 --- a/DynamORM/DynamicConnection.cs +++ b/DynamORM/DynamicConnection.cs @@ -32,14 +32,14 @@ using System.Data; namespace DynamORM { /// Connection wrapper. - /// This class is only connection holder conection is managed by + /// This class is only connection holder, connection is managed by /// instance. public class DynamicConnection : IDbConnection, IDisposable { private DynamicDatabase _db; private bool _singleTransaction; - /// Gets underlaying connection. + /// Gets underlying connection. internal IDbConnection Connection { get; private set; } /// Initializes a new instance of the class. @@ -89,7 +89,7 @@ namespace DynamORM /// Changes the current database for an open Connection object. /// The name of the database to use in place of the current database. - /// This operation is not supported in DynamORM. and will throw . + /// This operation is not supported in DynamORM. and will throw . /// Thrown always. public void ChangeDatabase(string databaseName) { @@ -107,12 +107,12 @@ namespace DynamORM /// Does nothing. handles /// closing connections. Only way to close it is to dispose connection. /// It will close if this is multi connection configuration, otherwise - /// it will stay open untill is not + /// it will stay open until is not /// disposed. public void Close() { } /// Gets or sets the string used to open a database. - /// Changing connection string operation is not supported in DynamORM. + /// Changing connection string operation is not supported in DynamORM. /// and will throw . /// Thrown always when set is attempted. public string ConnectionString diff --git a/DynamORM/DynamicDatabase.cs b/DynamORM/DynamicDatabase.cs index 7995a86..2651bf7 100644 --- a/DynamORM/DynamicDatabase.cs +++ b/DynamORM/DynamicDatabase.cs @@ -108,7 +108,7 @@ namespace DynamORM public bool DumpCommands { get; set; } /// Initializes a new instance of the class. - /// Database proider by name. + /// Database provider by name. /// Connection string to provided database. /// Connection options. public DynamicDatabase(string provider, string connectionString, DynamicDatabaseOptions options) @@ -117,7 +117,7 @@ namespace DynamORM } /// Initializes a new instance of the class. - /// Database proider. + /// Database provider. /// Connection string to provided database. /// Connection options. public DynamicDatabase(DbProviderFactory provider, string connectionString, DynamicDatabaseOptions options) @@ -146,6 +146,7 @@ namespace DynamORM _singleConnection = (options & DynamicDatabaseOptions.SingleConnection) == DynamicDatabaseOptions.SingleConnection; _singleTransaction = (options & DynamicDatabaseOptions.SingleTransaction) == DynamicDatabaseOptions.SingleTransaction; + DumpCommands = (options & DynamicDatabaseOptions.DumpCommands) == DynamicDatabaseOptions.DumpCommands; TransactionPool = new Dictionary>(); CommandsPool = new Dictionary>(); @@ -158,7 +159,7 @@ namespace DynamORM #region Table /// Gets dynamic table which is a simple ORM using dynamic objects. - /// The action with nstance of as parameter. + /// The action with instance of as parameter. /// Table name. /// Override keys in schema. public void Table(Action action, string table = "", string[] keys = null) @@ -169,7 +170,7 @@ namespace DynamORM /// Gets dynamic table which is a simple ORM using dynamic objects. /// Type used to determine table name. - /// The action with nstance of as parameter. + /// The action with instance of as parameter. /// Override keys in schema. public void Table(Action action, string[] keys = null) { @@ -228,9 +229,9 @@ namespace DynamORM #region Schema - /// Builds table cache if nessesary and returns it. + /// Builds table cache if necessary and returns it. /// Name of table for which build schema. - /// Table chema. + /// Table schema. public Dictionary GetSchema(string table) { Dictionary schema = null; @@ -242,7 +243,7 @@ namespace DynamORM return schema; } - /// Builds table cache if nessesary and returns it. + /// Builds table cache if necessary and returns it. /// Type of table for which build schema. /// Table schema or null if type was anonymous. public Dictionary GetSchema() @@ -259,7 +260,7 @@ namespace DynamORM return schema; } - /// Builds table cache if nessesary and returns it. + /// Builds table cache if necessary and returns it. /// Type of table for which build schema. /// Table schema or null if type was anonymous. public Dictionary GetSchema(Type table) @@ -558,7 +559,7 @@ namespace DynamORM /// Begins a global database transaction. /// Using this method connection is set to single open - /// connection untill all transactions are finished. + /// connection until all transactions are finished. /// Returns representation. public IDbTransaction BeginTransaction() { diff --git a/DynamORM/DynamicDatabaseOptions.cs b/DynamORM/DynamicDatabaseOptions.cs index 83d986e..3410c45 100644 --- a/DynamORM/DynamicDatabaseOptions.cs +++ b/DynamORM/DynamicDatabaseOptions.cs @@ -32,27 +32,31 @@ namespace DynamORM { /// Represents database connection options. [Flags] + [System.Reflection.ObfuscationAttribute(Feature = "renaming", ApplyToMembers = true)] public enum DynamicDatabaseOptions { /// No specific options. - None, + None = 0x00000000, - /// Only single presistent database connection. - SingleConnection, + /// Only single persistent database connection. + SingleConnection = 0x00000001, /// Only one transaction. - SingleTransaction, + SingleTransaction = 0x00000002, /// Database supports top syntax (SELECT TOP x ... FROM ...). - SupportTop, + SupportTop = 0x00000080, /// Database supports limit offset syntax (SELECT ... FROM ... LIMIT x OFFSET y). - SupportLimitOffset, + SupportLimitOffset = 0x00000040, /// Database support standard schema. - SupportSchema, + SupportSchema = 0x00000010, - /// Database support stored procedures (EXEC proc ...). - SupportStoredProcedures + /// Database support stored procedures (EXEC procedure ...). + SupportStoredProcedures = 0x00000020, + + /// Debug option allowing to enable command dumps by default. + DumpCommands = 0x01000000, } } \ No newline at end of file diff --git a/DynamORM/DynamicExtensions.cs b/DynamORM/DynamicExtensions.cs index b5a7e48..c072fc0 100644 --- a/DynamORM/DynamicExtensions.cs +++ b/DynamORM/DynamicExtensions.cs @@ -46,7 +46,7 @@ namespace DynamORM { #region Type column map - /// MapEnumerable of .NET types to DbType's. + /// MapEnumerable of .NET types to . public static readonly Dictionary TypeMap = new Dictionary() { { typeof(byte), DbType.Byte }, @@ -115,7 +115,7 @@ namespace DynamORM /// Set properties on the fly. /// in which changes will be made. - /// Indicates or specifies how the System.Data.IDbCommand.CommandText property is interpreted. + /// Indicates or specifies how the property is interpreted. /// The wait time before terminating the attempt to execute a command and generating an error. /// The text command to run against the data source. /// Arguments used to format command. @@ -153,7 +153,7 @@ namespace DynamORM /// Set properties on the fly. /// in which changes will be made. - /// Indicates or specifies how the System.Data.IDbCommand.CommandText property is interpreted. + /// Indicates or specifies how the property is interpreted. /// The text command to run against the data source. /// Arguments used to format command. /// Returns edited instance. @@ -248,7 +248,7 @@ namespace DynamORM var p = cmd.CreateParameter(); p.ParameterName = name; - if (item == null) + if (item == null || item == DBNull.Value) p.Value = DBNull.Value; else { @@ -298,7 +298,7 @@ namespace DynamORM p.Scale = 4; } - p.Value = item.Value; + p.Value = item.Value == null ? DBNull.Value : item.Value; } else if (item.Value == null || item.Value == DBNull.Value) p.Value = DBNull.Value; @@ -308,6 +308,8 @@ namespace DynamORM if (p.DbType == DbType.String) p.Size = item.Value.ToString().Length > 4000 ? -1 : 4000; + + p.Value = item.Value; } cmd.Parameters.Add(p); @@ -703,7 +705,7 @@ namespace DynamORM param.Scale, param.Precision, param.Scale, - param.Value ?? "NULL", + param.Value is byte[] ? ConvertByteArrayToHexString((byte[])param.Value) : param.Value ?? "NULL", param.Value != null ? param.Value.GetType().Name : "DBNull"); } @@ -713,6 +715,32 @@ namespace DynamORM return command; } + /// Convert byte array to hex formatted string without separators. + /// Byte Array Data. + /// Hex string representation of byte array. + private static string ConvertByteArrayToHexString(byte[] data) + { + return ConvertByteArrayToHexString(data, 0); + } + + /// Convert byte array to hex formatted string. + /// Byte Array Data. + /// Put '-' each separatorEach characters. + /// Hex string representation of byte array. + private static string ConvertByteArrayToHexString(byte[] data, int separatorEach) + { + int len = data.Length * 2; + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + for (int i = 0; i < len; i++) + { + sb.AppendFormat("{0:X}", data[(i / 2)] >> (((i % 2) == 0) ? 4 : 0) & 0x0F); + if ((separatorEach > 0) && ((i + 1) % separatorEach == 0)) + sb.AppendFormat("-"); + } + + return sb.ToString(); + } + #endregion Command extensions #region Dynamic extensions @@ -751,10 +779,16 @@ namespace DynamORM { var result = new ExpandoObject(); var dict = result as IDictionary; + var ot = o.GetType(); - if (o.GetType() == typeof(ExpandoObject)) + if (ot == typeof(ExpandoObject)) return o; - if (o.GetType() == typeof(NameValueCollection) || o.GetType().IsSubclassOf(typeof(NameValueCollection))) + + if (o is IDictionary) + ((IDictionary)o) + .ToList() + .ForEach(kvp => dict.Add(kvp.Key, kvp.Value)); + else if (ot == typeof(NameValueCollection) || ot.IsSubclassOf(typeof(NameValueCollection))) { var nameValue = (NameValueCollection)o; nameValue.Cast() @@ -764,7 +798,7 @@ namespace DynamORM } else { - var mapper = DynamicMapperCache.GetMapper(o.GetType()); + var mapper = DynamicMapperCache.GetMapper(ot); if (mapper != null) { @@ -774,7 +808,7 @@ namespace DynamORM } else { - var props = o.GetType().GetProperties(); + var props = ot.GetProperties(); foreach (var item in props) if (item.CanRead) @@ -804,7 +838,7 @@ namespace DynamORM /// Convert data row row into dynamic object (upper case key). /// DataRow from which read. /// Generated dynamic object. - internal static dynamic RowToDynamicUpper(this DataRow r) + public static dynamic RowToDynamicUpper(this DataRow r) { dynamic e = new ExpandoObject(); var d = e as IDictionary; @@ -845,7 +879,9 @@ namespace DynamORM /// Resulting dictionary. public static IDictionary ToDictionary(this object o) { - return (IDictionary)o.ToDynamic(); + return o is IDictionary ? + (IDictionary)o : + (IDictionary)o.ToDynamic(); } #endregion Dynamic extensions @@ -987,7 +1023,7 @@ namespace DynamORM return (T)mapper.Create(item); } - /// Fill object of speciied type with data from source object. + /// Fill object of specified type with data from source object. /// Type to which columnMap results. /// Item to which columnMap data. /// Item from which extract data. diff --git a/DynamORM/DynamicTable.cs b/DynamORM/DynamicTable.cs index 69256cd..454cfcb 100644 --- a/DynamORM/DynamicTable.cs +++ b/DynamORM/DynamicTable.cs @@ -41,7 +41,7 @@ namespace DynamORM /// /// Assume that we have a table representing Users class. /// - /// Let's take a look at Query posibilities. Assume we want + /// Let's take a look at Query possibilities. Assume we want /// to get enumerator for all records in database, mapped to our class /// instead of dynamic type we can use following syntax. /// Approach first. Use dynamic Query method and just set type @@ -54,13 +54,13 @@ namespace DynamORM /// IEnumerable<object> (to which we must cast to) to map /// object. /// (db.Table<User>().Query(columns: "*") as IEnumerable<object>).MapEnumerable<User>(); - /// You can also use generic approach. But be careful this method is currently avaliable thanks to framework hack. + /// You can also use generic approach. But be careful this method is currently available thanks to framework hack. /// (db.Table<User>().Query<User>() as IEnumerable<object>).Cast<User>() /// Another approach uses existing methods, but still requires a /// cast, because Query also returns dynamic object enumerator. /// (db.Table<User>().Query().Execute() as IEnumerable<object>).MapEnumerable<User>(); /// - /// Below you can find various invocations of dynamic and non dynemic + /// Below you can find various invocations of dynamic and non dynamic /// methods of this class. x variable is a class instance. /// First various selects: /// x.Count(columns: "id"); @@ -215,7 +215,9 @@ namespace DynamORM /// If database doesn't support schema, only key columns are listed here. public virtual Dictionary Schema { get; private set; } - private DynamicTable() { } + private DynamicTable() + { + } /// Initializes a new instance of the class. /// Database and connection management. @@ -311,8 +313,8 @@ namespace DynamORM #region Basic Queries /// Enumerate the reader and yield the result. - /// Sql query containing numered parameters in format provided by - /// methods. Also names should be formated with + /// SQL query containing numbered parameters in format provided by + /// methods. Also names should be formatted with /// method. /// Arguments (parameters). /// Enumerator of objects expanded from query. @@ -354,8 +356,8 @@ namespace DynamORM } /// Returns a single result. - /// Sql query containing numered parameters in format provided by - /// methods. Also names should be formated with + /// SQL query containing numbered parameters in format provided by + /// methods. Also names should be formatted with /// method. /// Arguments (parameters). /// Result of a query. @@ -403,8 +405,8 @@ namespace DynamORM } /// Execute non query. - /// Sql query containing numered parameters in format provided by - /// methods. Also names should be formated with + /// SQL query containing numbered parameters in format provided by + /// methods. Also names should be formatted with /// method. /// Arguments (parameters). /// Number of affected rows. @@ -472,9 +474,9 @@ namespace DynamORM return new DynamicInsertQueryBuilder(this); } - /// Adds a record to the database. You can pass in an Anonymous object, an ExpandoObject, - /// A regular old POCO, or a NameValueColletion from a Request.Form or Request.QueryString. - /// Anonymous object, an ExpandoObject, a regular old POCO, or a NameValueCollection + /// Adds a record to the database. You can pass in an Anonymous object, an , + /// A regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString. + /// Anonymous object, an , a regular old POCO, or a NameValueCollection /// from a Request.Form or Request.QueryString, containing fields to update. /// Number of updated rows. public virtual int Insert(object o) @@ -499,7 +501,7 @@ namespace DynamORM /// a regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString. /// Anonymous object, an ExpandoObject, a regular old POCO, or a NameValueCollection /// from a Request.Form or Request.QueryString, containing fields to update. - /// Anonymous object, an ExpandoObject, a regular old POCO, or a NameValueCollection + /// Anonymous object, an , a regular old POCO, or a NameValueCollection /// from a Request.Form or Request.QueryString, containing fields with conditions. /// Number of updated rows. public virtual int Update(object o, object key) @@ -512,7 +514,7 @@ namespace DynamORM /// Updates a record in the database using schema. You can pass in an Anonymous object, an ExpandoObject, /// a regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString. - /// Anonymous object, an ExpandoObject, a regular old POCO, or a NameValueCollection + /// Anonymous object, an , a regular old POCO, or a NameValueCollection /// from a Request.Form or Request.QueryString, containing fields to update and conditions. /// Number of updated rows. public virtual int Update(object o) @@ -533,9 +535,9 @@ namespace DynamORM return new DynamicDeleteQueryBuilder(this); } - /// Removes a record from the database. You can pass in an Anonymous object, an ExpandoObject, - /// A regular old POCO, or a NameValueColletion from a Request.Form or Request.QueryString. - /// Anonymous object, an ExpandoObject, a regular old POCO, or a NameValueCollection + /// Removes a record from the database. You can pass in an Anonymous object, an , + /// A regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString. + /// Anonymous object, an , a regular old POCO, or a NameValueCollection /// from a Request.Form or Request.QueryString, containing fields with where conditions. /// If true use schema to determine key columns and ignore those which /// aren't keys. @@ -579,12 +581,15 @@ namespace DynamORM case "Insert": result = DynamicInsert(args, info, types); break; + case "Update": result = DynamicUpdate(args, info, types); break; + case "Delete": result = DynamicDelete(args, info, types); break; + default: result = DynamicQuery(args, info, op, types); break; @@ -614,14 +619,17 @@ namespace DynamORM builder.Table(args[i].ToString()); else goto default; break; + case "values": builder.Insert(args[i]); break; + case "type": if (types == null || types.Count == 0) HandleTypeArgument(args, info, ref types, builder, i); else goto default; break; + default: builder.Insert(name, args[i]); break; @@ -654,20 +662,25 @@ namespace DynamORM builder.Table(args[i].ToString()); else goto default; break; + case "update": builder.Update(args[i]); break; + case "values": builder.Values(args[i]); break; + case "where": builder.Where(args[i]); break; + case "type": if (types == null || types.Count == 0) HandleTypeArgument(args, info, ref types, builder, i); else goto default; break; + default: builder.Update(name, args[i]); break; @@ -700,17 +713,21 @@ namespace DynamORM builder.Table(args[i].ToString()); else goto default; break; + case "where": builder.Where(args[i], false); break; + case "delete": builder.Where(args[i], true); break; + case "type": if (types == null || types.Count == 0) HandleTypeArgument(args, info, ref types, builder, i); else goto default; break; + default: builder.Where(name, args[i]); break; @@ -751,6 +768,7 @@ namespace DynamORM builder.OrderBy((DynamicColumn)args[i]); else goto default; break; + case "group": if (args[i] is string) builder.GroupBy(((string)args[i]).Split(',')); @@ -762,6 +780,7 @@ namespace DynamORM builder.GroupBy((DynamicColumn)args[i]); else goto default; break; + case "columns": if (args[i] is string) builder.Select(((string)args[i]).Split(',')); @@ -773,19 +792,23 @@ namespace DynamORM builder.Select((DynamicColumn)args[i]); else goto default; break; + case "where": builder.Where(args[i]); break; + case "table": if (args[i] is string) builder.Table(args[i].ToString()); else goto default; break; + case "type": if (types == null || types.Count == 0) HandleTypeArgument(args, info, ref types, builder, i); else goto default; break; + default: builder.Where(name, args[i]); break; @@ -820,6 +843,8 @@ namespace DynamORM if (op == "Count" && result is long) result = (int)(long)result; + else if (result == DBNull.Value) + result = null; } else { @@ -851,7 +876,7 @@ namespace DynamORM if (op == "Scalar") { if (builder.Columns.Count != 1) - throw new InvalidOperationException("You must select one column in scalar steatement."); + throw new InvalidOperationException("You must select one column in scalar statement."); result = Scalar(builder); } @@ -905,11 +930,12 @@ namespace DynamORM /// freeing, releasing, or resetting unmanaged resources. public void Dispose() { - Database.RemoveFromCache(this); - // Lose reference but don't kill it. if (Database != null) + { + Database.RemoveFromCache(this); Database = null; + } } #endregion IDisposable Members diff --git a/DynamORM/Helpers/FrameworkTools.cs b/DynamORM/Helpers/FrameworkTools.cs index a16de37..bd74d67 100644 --- a/DynamORM/Helpers/FrameworkTools.cs +++ b/DynamORM/Helpers/FrameworkTools.cs @@ -39,7 +39,7 @@ namespace DynamORM.Helpers { #region Mono or .NET Framework detection - /// This is preaty simple trick. + /// This is pretty simple trick. private static bool _isMono = Type.GetType("Mono.Runtime") != null; /// Gets a value indicating whether application is running under mono runtime. @@ -98,7 +98,7 @@ namespace DynamORM.Helpers return null; } - /// Extension method allowing to easyly extract generic type + /// Extension method allowing to easily extract generic type /// arguments from assuming that it /// inherits from /// Microsoft.CSharp.RuntimeBinder.ICSharpInvokeOrInvokeMemberBinder diff --git a/DynamORM/Mapper/DynamicMapperCache.cs b/DynamORM/Mapper/DynamicMapperCache.cs index a947b9f..3ae3688 100644 --- a/DynamORM/Mapper/DynamicMapperCache.cs +++ b/DynamORM/Mapper/DynamicMapperCache.cs @@ -31,7 +31,7 @@ using System.Collections.Generic; namespace DynamORM.Mapper { - /// Class with maper cache. + /// Class with mapper cache. public static class DynamicMapperCache { private static readonly object SyncLock = new object(); diff --git a/DynamORM/Mapper/DynamicTypeMap.cs b/DynamORM/Mapper/DynamicTypeMap.cs index 4cd1895..07e7a59 100644 --- a/DynamORM/Mapper/DynamicTypeMap.cs +++ b/DynamORM/Mapper/DynamicTypeMap.cs @@ -106,7 +106,7 @@ namespace DynamORM.Mapper } /// Create object of type and fill values from source. - /// Object containing values that will be mapped to newy created object. + /// Object containing values that will be mapped to newly created object. /// New object of type with matching values from source. public object Create(object source) { @@ -114,7 +114,7 @@ namespace DynamORM.Mapper } /// Fill values from source to object in destination. - /// Object containing values that will be mapped to newy created object. + /// Object containing values that will be mapped to newly created object. /// Object of type to which copy values from source. /// Object of type with matching values from source. public object Map(object source, object destination) diff --git a/DynamORM/Mapper/TableAttribute.cs b/DynamORM/Mapper/TableAttribute.cs index 02aa020..49fe2a0 100644 --- a/DynamORM/Mapper/TableAttribute.cs +++ b/DynamORM/Mapper/TableAttribute.cs @@ -37,9 +37,9 @@ namespace DynamORM.Mapper /// Gets or sets name. public string Name { get; set; } - /// Gets or sets a value indicating whether overide database + /// Gets or sets a value indicating whether override database /// schema values. - /// If database doeesn't support schema, you still have to + /// If database doesn't support schema, you still have to /// set this to true to get schema from type. public bool Override { get; set; } }