diff --git a/ACUtils.SqlDb.Utils/ACUtils.SqlDb.Utils.csproj b/ACUtils.SqlDb.Utils/ACUtils.SqlDb.Utils.csproj
index 42c4c6c..2449e96 100644
--- a/ACUtils.SqlDb.Utils/ACUtils.SqlDb.Utils.csproj
+++ b/ACUtils.SqlDb.Utils/ACUtils.SqlDb.Utils.csproj
@@ -4,8 +4,8 @@
Andrea Cattaneo
true
false
- 1.0.0.147
- 1.0.0.147
+ 1.0.0.148
+ 1.0.0.148
Utilities per gestione DataTable
it
true
diff --git a/ACUtils.SqlDb.Utils/DBModel.cs b/ACUtils.SqlDb.Utils/DBModel.cs
index 9a55a61..22ce1ab 100644
--- a/ACUtils.SqlDb.Utils/DBModel.cs
+++ b/ACUtils.SqlDb.Utils/DBModel.cs
@@ -118,7 +118,7 @@ public Q GetValueByDbAttribute(string field)
{
return GetValueBy(field, property => GetDbAttribute(property.Name)?.DbField);
}
-
+
public object this[string fieldName]
{
get
@@ -297,6 +297,14 @@ public IDbFieldAttribute GetDbAttribute(string propertyName)
return attrs.LastOrDefault() as IDbFieldAttribute;
}
+ public static IDbFieldAttribute GetDbAttribute(string propertyName)
+ {
+ var type = typeof(T);
+ var propr = type.GetProperty(propertyName);
+ var attrs = propr?.GetCustomAttributes(typeof(IDbFieldAttribute), true);
+ return attrs?.LastOrDefault() as IDbFieldAttribute;
+ }
+
}
diff --git a/ACUtils.SqlDb/ACUtils.SqlDb.csproj b/ACUtils.SqlDb/ACUtils.SqlDb.csproj
index 794799b..79e0234 100644
--- a/ACUtils.SqlDb/ACUtils.SqlDb.csproj
+++ b/ACUtils.SqlDb/ACUtils.SqlDb.csproj
@@ -5,8 +5,8 @@
Andrea Cattaneo
true
false
- 1.0.0.154
- 1.0.0.154
+ 1.0.0.155
+ 1.0.0.155
Utility per interrogazione database MSSQL
it
true
diff --git a/ACUtils.SqlDb/SqlDb.cs b/ACUtils.SqlDb/SqlDb.cs
index 5fa0129..8675e2c 100644
--- a/ACUtils.SqlDb/SqlDb.cs
+++ b/ACUtils.SqlDb/SqlDb.cs
@@ -254,7 +254,7 @@ public static DataTable ToDataTable(IEnumerable l_oItems)
int i;
//#### Collect the a_oProperties for the passed T
- System.Reflection.PropertyInfo[] a_oProperties = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+ System.Reflection.PropertyInfo[] a_oProperties = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Where(p => p.CanRead && !p.DeclaringType.IsConstructedGenericType).ToArray();
//#### Traverse each oProperty, .Add'ing each .Name/.BaseType into our oReturn value
//#### NOTE: The call to .BaseType is required as DataTables/DataSets do not support nullable types, so it's non-nullable counterpart Type is required in the .Column definition
diff --git a/ACUtils.SqlDb/SqlDb_BulkInsert.cs b/ACUtils.SqlDb/SqlDb_BulkInsert.cs
index e2bae0f..a0d91b1 100644
--- a/ACUtils.SqlDb/SqlDb_BulkInsert.cs
+++ b/ACUtils.SqlDb/SqlDb_BulkInsert.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
+using System.Linq;
namespace ACUtils
{
@@ -16,6 +17,7 @@ public static void BulkInsert(this SqlDb self, string tablename, IEnumerable<
}
}
}
+
public static async System.Threading.Tasks.Task BulkInsertAsync(this SqlDb self, string tablename, IEnumerable records)
{
using (var connection = await self._getConnectionAsync())
@@ -30,10 +32,11 @@ public static async System.Threading.Tasks.Task BulkInsertAsync(this SqlDb se
internal static DataTable BulkInsertPrepare(this SqlDb self, SqlBulkCopy bc, string tablename, IEnumerable records)
{
bc.DestinationTableName = tablename;
- var properties = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+ var properties = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Where(p => p.CanRead && !p.DeclaringType.IsConstructedGenericType);
foreach (var property in properties)
{
- bc.ColumnMappings.Add(property.Name, property.Name);
+ var attr = DBModel.GetDbAttribute(propertyName: property.Name);
+ bc.ColumnMappings.Add(property.Name, attr?.DbField ?? property.Name);
}
return SqlDb.ToDataTable(records);
}
diff --git a/Tests/SqlDbTest.cs b/Tests/SqlDbTest.cs
index b28a15f..a3cf42f 100644
--- a/Tests/SqlDbTest.cs
+++ b/Tests/SqlDbTest.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Data;
using System.Linq;
using System.Transactions;
@@ -156,9 +157,10 @@ public void TestQueryDictionary()
}
- class DbPerson: ACUtils.DBModel
+ class DbPerson : ACUtils.DBModel
{
- public int BusinessEntityID { get; set; }
+ [DbField("BusinessEntityID")]
+ public int Id { get; set; }
public string PersonType { get; set; }
public string Title { get; set; }
public string FirstName { get; set; }
@@ -175,5 +177,54 @@ public void TestQueryMany()
Assert.AreEqual(count, allPersons.ToList().Count);
}
+
+
+ [TestCase(100, false)]
+ [TestCase(100, true)]
+ public void TestBulkInsert(int rows, bool async)
+ {
+ // prepare
+ var nextId = db.QuerySingleValue("SELECT MAX(BusinessEntityID) + 1 FROM Person.Person");
+ var initialCount = db.QuerySingleValue("SELECT COUNT(*) FROM Person.Person");
+ var objects = new List();
+ for (int i = nextId; i < (nextId + rows); i++)
+ {
+ objects.Add(new DbPerson()
+ {
+ Id = i,
+ PersonType = "EM",
+ Title = "Test",
+ FirstName = $"FirstName {i}",
+ MiddleName = $"MiddleName {i}",
+ LastName = $"LastName {i}",
+ });
+ }
+
+ // execute
+ if (async)
+ {
+ db.BulkInsertAsync("Person.Person", objects).Wait();
+ }
+ else
+ {
+ db.BulkInsert("Person.Person", objects);
+ }
+
+ // test
+ var finalCount = db.QuerySingleValue("SELECT COUNT(*) FROM Person.Person");
+ Assert.AreEqual(initialCount + rows, finalCount);
+
+ foreach (var person in objects)
+ {
+ Assert.IsTrue(person.Id > 0);
+ var dr = db.QueryDataRow("SELECT * FROM Person.Person WHERE BusinessEntityID = @ID", "@ID".WithValue(person.Id));
+ Assert.AreEqual(person.Id, dr.Field("BusinessEntityID"));
+ Assert.AreEqual(person.PersonType, dr.Field("PersonType"));
+ Assert.AreEqual(person.Title, dr.Field("Title"));
+ Assert.AreEqual(person.FirstName, dr.Field("FirstName"));
+ Assert.AreEqual(person.MiddleName, dr.Field("MiddleName"));
+ Assert.AreEqual(person.LastName, dr.Field("LastName"));
+ }
+ }
}
}
diff --git a/Tests/SqlDbUtilsTest.cs b/Tests/SqlDbUtilsTest.cs
index d0c2d20..0e3cd0b 100644
--- a/Tests/SqlDbUtilsTest.cs
+++ b/Tests/SqlDbUtilsTest.cs
@@ -17,11 +17,20 @@ public class TestDbModel : DBModel
public int? nullableIntValue { get; set; }
public int intValue { get; set; }
public decimal decimalValue { get; set; }
+ [DbField("DB_FILE_NAME_FLOAT")]
public float floatValue { get; set; }
public DateTime datetimeValue { get; set; }
}
+ internal class TestGetDbAttributeClass: DBModel
+ {
+ public decimal decimalValue { get; set; }
+ [DbField("DB_FILE_NAME_FLOAT")]
+ public float floatValue { get; set; }
+ public DateTime datetimeValue { get; set; }
+ }
+
[TestFixture]
class SqlDbUtilsTest
{
@@ -41,7 +50,7 @@ void _generateDt()
_testDt.Columns.Add("stringValue", typeof(string));
_testDt.Columns.Add("intValue", typeof(int));
_testDt.Columns.Add("decimalValue", typeof(decimal));
- _testDt.Columns.Add("floatValue", typeof(float));
+ _testDt.Columns.Add("DB_FILE_NAME_FLOAT", typeof(float));
_testDt.Columns.Add("datetimeValue", typeof(DateTime));
for (int i = 0; i < DT_SIZE; i++)
{
@@ -49,7 +58,7 @@ void _generateDt()
dr["stringValue"] = i.ToString();
dr["intValue"] = i;
dr["decimalValue"] = new Decimal(i / 2);
- dr["floatValue"] = (float)i / 2;
+ dr["DB_FILE_NAME_FLOAT"] = (float)i / 2;
dr["datetimeValue"] = DateTime.Now;
_testDt.Rows.Add(dr);
}
@@ -79,6 +88,25 @@ public void testIdrateObj()
}
}
+
+ [Test]
+ public void testGetDbAttribute()
+ {
+ Assert.AreEqual("DB_FILE_NAME_FLOAT", DBModel.GetDbAttribute("floatValue").DbField);
+ Assert.AreEqual("DB_FILE_NAME_FLOAT", DBModel.GetDbAttribute("floatValue").DbField);
+
+ var model = new TestDbModel();
+ Assert.AreEqual("DB_FILE_NAME_FLOAT", model.GetDbAttribute("floatValue").DbField);
+
+ var model2 = new TestGetDbAttributeClass();
+ Assert.AreEqual("DB_FILE_NAME_FLOAT", model2.GetDbAttribute("floatValue").DbField);
+
+
+ Assert.IsNull(DBModel.GetDbAttribute("stringValue"));
+
+ Assert.IsNull(DBModel.GetDbAttribute("not exists property"));
+ }
+
[Test]
public void testStaticIdrate()
{