diff --git a/Source/EntityFramework.Extended.Test/EntityFramework.Extended.Test.csproj b/Source/EntityFramework.Extended.Test/EntityFramework.Extended.Test.csproj
index 33cb4b9..4f119da 100644
--- a/Source/EntityFramework.Extended.Test/EntityFramework.Extended.Test.csproj
+++ b/Source/EntityFramework.Extended.Test/EntityFramework.Extended.Test.csproj
@@ -80,6 +80,7 @@
+
diff --git a/Source/EntityFramework.Extended.Test/InsertSqlGenerationTests.cs b/Source/EntityFramework.Extended.Test/InsertSqlGenerationTests.cs
new file mode 100644
index 0000000..8e5ae4e
--- /dev/null
+++ b/Source/EntityFramework.Extended.Test/InsertSqlGenerationTests.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Data.Entity;
+using System.Linq;
+using EntityFramework.Extensions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace EntityFramework.Test
+{
+ [TestClass]
+ public class InsertSqlGenerationTests
+ {
+ private IQueryable linqQuery;
+
+ [TestInitialize]
+ public void TestFixtureSetUp()
+ {
+ Database.SetInitializer(null);
+
+ linqQuery = new Repository().GetAll()
+ .Select(person => person);
+ }
+
+ [TestMethod]
+ public void SelectIntoTempTableFromLinq()
+ {
+ string insertSql = linqQuery.SelectInsertSql("#tmp");
+ Console.WriteLine(insertSql);
+ StringAssert.Contains(insertSql, " INTO #tmp FROM ");
+ }
+
+ [TestMethod]
+ public void InsertSelectFromLinq()
+ {
+ string insertSql = linqQuery.InsertIntoSql("TableNameToInsert", "Id, FirstName, LastName");
+ Console.WriteLine(insertSql);
+ StringAssert.Contains(insertSql, "INSERT INTO TableNameToInsert (Id, FirstName, LastName)\r\nSELECT");
+
+ Console.WriteLine();
+ string insertSqlSimple = linqQuery.InsertIntoSql("TableNameToInsert");
+ Console.WriteLine(insertSqlSimple);
+ StringAssert.Contains(insertSqlSimple, "INSERT INTO TableNameToInsert \r\nSELECT");
+ }
+ }
+
+ public class Person
+ {
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ }
+
+ public class Repository
+ where TAggregateRoot : class
+ {
+ private DbContext _dbContext = new TestContext();
+
+ public IQueryable GetAll()
+ {
+ return _dbContext.Set();
+ }
+ }
+
+ public class TestContext
+ : DbContext
+ {
+ public DbSet Persons { get; set; }
+ }
+
+}
diff --git a/Source/EntityFramework.Extended/EntityFramework.Extended.csproj b/Source/EntityFramework.Extended/EntityFramework.Extended.csproj
index 5d35fef..47f43df 100644
--- a/Source/EntityFramework.Extended/EntityFramework.Extended.csproj
+++ b/Source/EntityFramework.Extended/EntityFramework.Extended.csproj
@@ -86,6 +86,7 @@
+
diff --git a/Source/EntityFramework.Extended/Extensions/ObjectQueryExtensions.cs b/Source/EntityFramework.Extended/Extensions/ObjectQueryExtensions.cs
index 69c1670..9d2de65 100644
--- a/Source/EntityFramework.Extended/Extensions/ObjectQueryExtensions.cs
+++ b/Source/EntityFramework.Extended/Extensions/ObjectQueryExtensions.cs
@@ -1,11 +1,9 @@
using System;
-using System.Collections.Generic;
-using System.Data.Common;
+using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;
using System.Linq;
using System.Linq.Expressions;
-using System.Text;
using EntityFramework.Reflection;
namespace EntityFramework.Extensions
@@ -124,5 +122,37 @@ public static ObjectContext GetContext(this IQueryable query)
return null;
}
+ ///
+ /// Captures SELECT ... FROM ... SQL from IDbSet, converts it into SELECT ... INTO ... T-SQL and executes it via context.ExecuteStoreCommand().
+ /// No objects are being brought into RAM / Context.
+ /// Only MS SQL Server and Sybase T-SQL RDBMS are supported.
+ /// Contributed by Agile Design LLC ( http://agiledesignllc.com/ ).
+ ///
+ /// Entity type
+ /// DbSet of entities
+ /// Target table name to insert into
+ public static void SelectInsert(this IQueryable source, string tableName)
+ where TEntity : class
+ {
+ source.GetContext()
+ .ExecuteStoreCommand(source.SelectInsertSql(tableName));
+ }
+
+ ///
+ /// Captures SELECT ... FROM ... SQL from IDbSet, converts it into INSERT INTO ... SELECT FROM ... ANSI-SQL
+ /// and executes it via context.ExecuteStoreCommand().
+ /// No objects are being brought into RAM / Context.
+ /// Contributed by Agile Design LLC ( http://agiledesignllc.com/ ).
+ ///
+ /// DbSet of entities
+ /// Target table name to insert into
+ /// Optional parameter for a list of columns to insert into
+ /// Entity type
+ public static void InsertInto(this IQueryable source, string tableName, string columnList = "")
+ where TEntity : class
+ {
+ source.GetContext()
+ .ExecuteStoreCommand(source.InsertIntoSql(tableName, columnList));
+ }
}
}
diff --git a/Source/EntityFramework.Extended/Extensions/QueryableExtensions.cs b/Source/EntityFramework.Extended/Extensions/QueryableExtensions.cs
new file mode 100644
index 0000000..e753311
--- /dev/null
+++ b/Source/EntityFramework.Extended/Extensions/QueryableExtensions.cs
@@ -0,0 +1,58 @@
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace EntityFramework.Extensions
+{
+ ///
+ /// Extension methods for IQueryable to support INSERT ... and SELECT INSERT ... SQL statements without loading objects into RAM.
+ /// Contributed by Agile Design LLC ( http://agiledesignllc.com/ ).
+ ///
+ public static class QueryableExtensions
+ {
+ private const string FromTableSqlExpression = @"\bFROM\b";
+
+ ///
+ /// Captures SELECT ... FROM ... SQL from IQueryable and converts it into SELECT ... INTO ... T-SQL.
+ /// No objects are being brought into RAM / Context.
+ /// Only MS SQL Server and Sybase T-SQL RDBMS are supported.
+ /// Contributed by Agile Design LLC ( http://agiledesignllc.com/ ).
+ ///
+ /// Entity type
+ /// DbSet of entities (or any IQueryable that returns SQL from its ToString() implementation
+ /// Target table name to insert into
+ /// SELECT ... INSERT ... T-SQL statement
+ public static string SelectInsertSql(this IQueryable source, string tableName)
+ {
+ var regex = new Regex(FromTableSqlExpression);
+ string selectInsertSql = regex.Replace(
+ source.ToString()
+ , string.Format(" INTO {0} FROM ", tableName)
+ , 1);
+
+ return selectInsertSql;
+ }
+
+ ///
+ /// Captures SELECT ... FROM ... SQL from IQueryable and converts it into INSERT INTO ... SELECT FROM ... ANSI-SQL.
+ /// No objects are being brought into RAM / Context.
+ /// Contributed by Agile Design LLC ( http://agiledesignllc.com/ ).
+ ///
+ /// Entity type
+ /// DbSet of entities (or any IQueryable that returns SQL from its ToString() implementation
+ /// Target table name to insert into
+ /// Optional parameter for a list of columns to insert into
+ /// INSERT INTO ... SELECT FROM ANSI-SQL statement
+ public static string InsertIntoSql(this IQueryable source, string tableName, string columnList = "")
+ {
+ string originalSql = source.ToString();
+ if (! string.IsNullOrWhiteSpace(columnList))
+ {
+ columnList = string.Format("({0})", columnList);
+ }
+ return string.Format("INSERT INTO {0} {1}\r\n{2}"
+ , tableName
+ , columnList
+ , originalSql);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Samples/net40/Tracker.SqlServer.CodeFirst/Entity.csp b/Source/Samples/net40/Tracker.SqlServer.CodeFirst/Entity.csp
index bc67dae..25ec03f 100644
--- a/Source/Samples/net40/Tracker.SqlServer.CodeFirst/Entity.csp
+++ b/Source/Samples/net40/Tracker.SqlServer.CodeFirst/Entity.csp
@@ -1,46 +1,46 @@
-
-
-
-
-
-
-
- .\
- .\Entities
- .\Mapping
- Singular
- Singular
- Plural
- Plural
-
-
- sysdiagrams$
-
-
- False
-
-
- ^(sp|tbl|udf|vw)_
-
-
- False
- False
- .\Queries
- By
- GetBy
- Key
- False
- .\Mocks
- True
- Tracker.SqlServer.CodeFirst
-
- $(TrackerConnectionString)
- SchemaExplorer.SqlSchemaProvider,SchemaExplorer.SqlSchemaProvider
-
- Tracker.SqlServer.CodeFirst.Mapping
- Tracker.SqlServer.CodeFirst.Entities
- Tracker.SqlServer.CodeFirst.Queries
- Tracker.SqlServer.CodeFirst.Mocks
-
-
+
+
+
+
+
+
+
+ .\
+ .\Entities
+ .\Mapping
+ Singular
+ Singular
+ Plural
+ Plural
+
+
+ sysdiagrams$
+
+
+ False
+
+
+ ^(sp|tbl|udf|vw)_
+
+
+ False
+ False
+ .\Queries
+ By
+ GetBy
+ Key
+ False
+ .\Mocks
+ True
+ Tracker.SqlServer.CodeFirst
+
+ $(TrackerConnectionString)
+ SchemaExplorer.SqlSchemaProvider,SchemaExplorer.SqlSchemaProvider
+
+ Tracker.SqlServer.CodeFirst.Mapping
+ Tracker.SqlServer.CodeFirst.Entities
+ Tracker.SqlServer.CodeFirst.Queries
+ Tracker.SqlServer.CodeFirst.Mocks
+
+
\ No newline at end of file