Skip to content
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
43 changes: 41 additions & 2 deletions QueryBuilder.Tests/InsertTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using SqlKata.Compilers;
using SqlKata.Tests.Infrastructure;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic;
using System.Linq;
using SqlKata.Compilers;
using SqlKata.Tests.Infrastructure;
using Xunit;

namespace SqlKata.Tests
Expand Down Expand Up @@ -284,6 +284,45 @@ public void InsertReadOnlyDictionary()
c[EngineCodes.Firebird]);
}

[Fact]
public void InsertDictionaryList()
{
var expensiveCars = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
{ "name", "Chiron" },
{ "brand", "Bugatti" },
{ "year", null },
},
new Dictionary<string, object>
{
{ "name", "Huayra" },
{ "year", 2012 },
{ "brand", "Pagani" },
},
new Dictionary<string, object>
{
{ "year", 2009 },
{ "brand", "Lamborghini" },
{ "name", "Reventon roadster" },
},
};

var query = new Query("expensive_cars")
.AsInsert(expensiveCars);

var c = Compile(query);

Assert.Equal(
"INSERT INTO [expensive_cars] ([brand], [name], [year]) VALUES ('Bugatti', 'Chiron', NULL), ('Pagani', 'Huayra', 2012), ('Lamborghini', 'Reventon roadster', 2009)",
c[EngineCodes.SqlServer]);

Assert.Equal(
"INSERT INTO \"EXPENSIVE_CARS\" (\"BRAND\", \"NAME\", \"YEAR\") SELECT 'Bugatti', 'Chiron', NULL FROM RDB$DATABASE UNION ALL SELECT 'Pagani', 'Huayra', 2012 FROM RDB$DATABASE UNION ALL SELECT 'Lamborghini', 'Reventon roadster', 2009 FROM RDB$DATABASE",
c[EngineCodes.Firebird]);
}

[Fact]
public void InsertExpandoObject()
{
Expand Down
42 changes: 41 additions & 1 deletion QueryBuilder/Query.Insert.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace SqlKata
{
Expand Down Expand Up @@ -97,6 +96,47 @@ public Query AsInsert(IEnumerable<string> columns, IEnumerable<IEnumerable<objec
return this;
}

public Query AsInsert(IEnumerable<IEnumerable<KeyValuePair<string, object>>> values)
{
if (values == null || !values.Any())
{
throw new InvalidOperationException($"{values} argument cannot be null or empty");
}

var columnsList = values.First().Select(x => x.Key).OrderBy(x => x).ToList();
if (!columnsList.Any())
{
throw new InvalidOperationException($"Elements in {values} argument cannot be empty");
}

var rowsValuesList = new List<List<object>>();

foreach (var rowValues in values)
{
int rowValuesCount = rowValues.Count();
if (rowValuesCount != columnsList.Count())
{
throw new InvalidOperationException($"Not all elements in {values} contain the same columns.");
}

var valuesList = new List<object>();
var sortedRowValuesList = rowValues.OrderBy(x => x.Key).ToList();
for (int i = 0; i < rowValuesCount; i++)
{
if (columnsList[i] != sortedRowValuesList[i].Key)
{
throw new InvalidOperationException($"Not all elements in {values} contain the same columns.");
}

valuesList.Add(sortedRowValuesList[i].Value);
}

rowsValuesList.Add(valuesList);
}

return AsInsert(columnsList, rowsValuesList);
}

/// <summary>
/// Produces insert from subquery
/// </summary>
Expand Down