How to create a temporary table and use it in the same connection with Entity Framework?
Asked Answered
C

2

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
...
...
...
Costanzo answered 25/7, 2016 at 23:43 Comment(5)
Try using the Table attribute on the class so [Table("#allRecords")] public class ResuleModel{}...Trencherman
where would I use that?Costanzo
On the ResuleModule class see #20185144 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 firstTrencherman
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() returnsCostanzo
Why not just place the temp table and query in one statement? (had a similar issue while using dapper and just combined the statement)Trencherman
E
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.

Egomania answered 26/7, 2016 at 0:11 Comment(1)
https://www.google.com/search?q=what%20is%20SSMSEgomania
E
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();
Earthy answered 30/7, 2020 at 14:6 Comment(1)
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 endCattle

© 2022 - 2024 — McMap. All rights reserved.