7

I am trying to execute a three raw queries with Entity Framework.

The first query will basically create a temporary table. The second query will add an index on the temporary table. Finally, the second query will join to the temporary table to other table to get a final dataset.

But every time I run my code, get the following error

invalid #allRecords object.

Here is what I have done

using (BaseContextdb = new BaseContext())
{
    using (var dbContextTransaction = db.Database.BeginTransaction())
    {
        try
        {
            db.Database.ExecuteSqlCommand("SELECT col1, col2, col3 " +
                                          "INTO #allRecords " +
                                          "FROM someTable " +
                                          "WHERE col5 = 'blab' " +
                                          "CREATE INDEX d ON #allRecords(col1, col2); ");

            var results = db.Database.SqlQuery<ResuleModel>(this.GetQuery()).ToList();

            db.SaveChanges();

            dbContextTransaction.Commit();
        }
        catch (Exception)
        {
            dbContextTransaction.Rollback();
        }
    }
}

how can I correctly create temporary table with Entity Framework?

UPDATED

Here is the query that is returned by this.GetQuery()

SELECT b.*, c.* 
FROM b
INNER JOIN #allRecords AS a ON a.col1 = v.col1 AND a.col2 = b.col2
INNER JOIN c ON c.Id= b.Id
...
...
...
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Jaylen
  • 39,043
  • 40
  • 128
  • 221
  • Try using the Table attribute on the class so [Table("#allRecords")] public class ResuleModel{}... – Alex Krupka Jul 25 '16 at 23:51
  • where would I use that? – Jaylen Jul 25 '16 at 23:52
  • On the ResuleModule class see http://stackoverflow.com/questions/20184644/howto-specify-table-name-with-entity-framework-code-first-fluent-api for an example --Second answer. And no I don't have a specific reason why I chose that link prob cause when I googled an example of Table Attribute usage it came up first – Alex Krupka Jul 25 '16 at 23:53
  • That would work if I wasn't using joins. the method `this.GetQuery()` return a complex query. I will update my question which what `this.GetQuery()` returns – Jaylen Jul 25 '16 at 23:55
  • Why not just place the temp table and query in one statement? (had a similar issue while using dapper and just combined the statement) – Alex Krupka Jul 26 '16 at 00:05

2 Answers2

4

Entity Framework doesn't work well with temporary tables.

Instead, you might want to look at Dapper. It is much cleaner; besides, you can use EF and Dapper in same project side-by-side. For example,

using (IDbConnection conn = new SqlConnection(DataBaseConnectionString))
{
   conn.Open();

   // If you want transaction, place it inside the query. 
   var entities = conn.Query<ResuleModel>(@"SELECT col1, col2, col3 ...");

   result = entities.ToList();
}

FYI: Make sure you execute the query in SSMS before using it in Dapper.

noelicus
  • 14,468
  • 3
  • 92
  • 111
Win
  • 61,100
  • 13
  • 102
  • 181
  • [https://www.google.com/search?q=what%20is%20SSMS](https://www.google.com/search?q=what%20is%20SSMS) – Win Jul 26 '16 at 16:19
1

Need to Open a new connection before you create, insert or query the temp table.
The opened connection will not be automatically closed until context disposal.

db.Database.Connection.Open();
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
  • `db.Database.OpenConnection()` works in EF Core 2.2. It is better to wrap this code inside `IDisposable` and do `db.Database.CloseConnection()` in the end – AndriiL Mar 05 '21 at 17:02