Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can add column for inserting only? #4

Open
wants to merge 5 commits into
base: IdentityOutput_Feature
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions SqlBulkTools.IntegrationTests/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="SqlBulkToolsTest" connectionString="Data Source=DESKTOP-6I9FL7M;Initial Catalog=SqlBulkTools;Integrated Security=True;Pooling=false" providerName="System.Data.SqlClient" />
<connectionStrings>
<!--<add name="SqlBulkToolsTest" connectionString="Data Source=DESKTOP-6I9FL7M;Initial Catalog=SqlBulkTools;Integrated Security=True;Pooling=false" providerName="System.Data.SqlClient" />-->
<add name="SqlBulkToolsTest" connectionString="Data Source=THINKPAD\SQLSERVER;Initial Catalog=SqlBulkTools;Integrated Security=True;Pooling=false" providerName="System.Data.SqlClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
Expand Down
2 changes: 2 additions & 0 deletions SqlBulkTools.IntegrationTests/Model/Book.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class Book
[Required]
[Index]
public decimal? Price { get; set; }

public float? TestFloat { get; set; }
}

}
21 changes: 21 additions & 0 deletions SqlBulkTools.IntegrationTests/Scripts/TestDataTypesTable.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CREATE TABLE [dbo].[TestDataTypes]
(
FloatTest float(24),
FloatTest2 float,
DecimalTest decimal(14,2),
MoneyTest money,
SmallMoneyTest smallmoney,
NumericTest numeric(30,2),
RealTest real,
DateTimeTest datetime,
DateTime2Test datetime2,
SmallDateTimeTest smalldatetime,
DateTest date,
TimeTest time,
GuidTest uniqueidentifier,
TextTest text,
VarBinaryTest varbinary(20),
BinaryTest binary(10),
TinyIntTest tinyint,
BigIntTest bigint
);
48 changes: 48 additions & 0 deletions SqlBulkTools.IntegrationTests/SqlBulkToolsIT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,54 @@ public void SqlBulkTools_WhenUsingReservedSqlKeywords()

}

[Test]
public void SqlBulkTools_BulkInsertOrUpdate_DecimalValueCorrectlySet()
{

_db.Books.RemoveRange(_db.Books.ToList());
_db.SaveChanges();

decimal? expectedPrice = (decimal?)1.33;

BulkOperations bulk = new BulkOperations();
List<Book> books = new List<Book>() { new Book() { Description = "Test", ISBN = "12345678910", Price = expectedPrice } };

bulk.Setup<Book>(x => x.ForCollection(books))
.WithTable("Books")
.AddAllColumns()
.BulkInsertOrUpdate()
.MatchTargetOn(x => x.ISBN)
.SetIdentityColumn(x => x.Id);

bulk.CommitTransaction("SqlBulkToolsTest");

Assert.AreEqual(_db.Books.First().Price, expectedPrice);

}

[Test]
public void SqlBulkTools_BulkInsertOrUpdae_FloatValueCorrectlySet()
{
_db.Books.RemoveRange(_db.Books.ToList());
_db.SaveChanges();

float? expectedFloat = (float?)1.33;

BulkOperations bulk = new BulkOperations();
List<Book> books = new List<Book>() { new Book() { Description = "Test", ISBN = "12345678910", Price = 30, TestFloat = expectedFloat} };

bulk.Setup<Book>(x => x.ForCollection(books))
.WithTable("Books")
.AddAllColumns()
.BulkInsertOrUpdate()
.MatchTargetOn(x => x.ISBN)
.SetIdentityColumn(x => x.Id);

bulk.CommitTransaction("SqlBulkToolsTest");

Assert.AreEqual(_db.Books.First().TestFloat, expectedFloat);
}


private void AppendToLogFile(string text)
{
Expand Down
78 changes: 64 additions & 14 deletions SqlBulkTools/BulkOperationsHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,49 @@ namespace SqlBulkTools
{
internal class BulkOperationsHelpers
{
internal struct PrecisionType
{
public string NumericPrecision { get; set; }
public string NumericScale { get; set; }
}

internal string BuildCreateTempTable(HashSet<string> columns, DataTable schema, bool? outputIdentity = null)
{
Dictionary<string, string> actualColumns = new Dictionary<string, string>();
Dictionary<string, string> actualColumnsMaxCharLength = new Dictionary<string, string>();
Dictionary<string, PrecisionType> actualColumnsPrecision = new Dictionary<string, PrecisionType>();


foreach (DataRow row in schema.Rows)
{
string columnType = row["DATA_TYPE"].ToString();
string columnName = row["COLUMN_NAME"].ToString();

actualColumns.Add(row["COLUMN_NAME"].ToString(), row["DATA_TYPE"].ToString());
actualColumnsMaxCharLength.Add(row["COLUMN_NAME"].ToString(),
row["CHARACTER_MAXIMUM_LENGTH"].ToString());

if (columnType == "varchar" || columnType == "nvarchar" ||
columnType == "char" || columnType == "binary" ||
columnType == "varbinary")

{
actualColumnsMaxCharLength.Add(row["COLUMN_NAME"].ToString(),
row["CHARACTER_MAXIMUM_LENGTH"].ToString());
}

if (columnType == "numeric" || columnType == "decimal")
{
PrecisionType p = new PrecisionType
{
NumericPrecision = row["NUMERIC_PRECISION"].ToString(),
NumericScale = row["NUMERIC_SCALE"].ToString()
};
actualColumnsPrecision.Add(columnName, p);
}

}

StringBuilder command = new StringBuilder();


command.Append("CREATE TABLE #TmpTable(");

List<string> paramList = new List<string>();
Expand All @@ -44,17 +71,8 @@ internal string BuildCreateTempTable(HashSet<string> columns, DataTable schema,
string columnType;
if (actualColumns.TryGetValue(column, out columnType))
{
if (columnType == "varchar" || columnType == "nvarchar")
{
string maxCharLength;
if (actualColumnsMaxCharLength.TryGetValue(column, out maxCharLength))
{
if (maxCharLength == "-1")
maxCharLength = "max";

columnType = columnType + "(" + maxCharLength + ")";
}
}
columnType = GetVariableCharType(column, columnType, actualColumnsMaxCharLength);
columnType = GetDecimalPrecisionAndScaleType(column, columnType, actualColumnsPrecision);
}

paramList.Add("[" + column + "]" + " " + columnType);
Expand All @@ -73,6 +91,38 @@ internal string BuildCreateTempTable(HashSet<string> columns, DataTable schema,
return command.ToString();
}

private string GetVariableCharType(string column, string columnType, Dictionary<string, string> actualColumnsMaxCharLength)
{
if (columnType == "varchar" || columnType == "nvarchar")
{
string maxCharLength;
if (actualColumnsMaxCharLength.TryGetValue(column, out maxCharLength))
{
if (maxCharLength == "-1")
maxCharLength = "max";

columnType = columnType + "(" + maxCharLength + ")";
}
}

return columnType;
}

private string GetDecimalPrecisionAndScaleType(string column, string columnType, Dictionary<string, PrecisionType> actualColumnsPrecision)
{
if (columnType == "decimal" || columnType == "numeric")
{
PrecisionType p;

if (actualColumnsPrecision.TryGetValue(column, out p))
{
columnType = columnType + "(" + p.NumericPrecision + ", " + p.NumericScale + ")";
}
}

return columnType;
}

internal string BuildJoinConditionsForUpdateOrInsert(string[] updateOn, string sourceAlias, string targetAlias)
{
StringBuilder command = new StringBuilder();
Expand Down