CSharp · Console
// Entity Framework Extensions
// Doc: https://entityframework-extensions.net/temporary-table#temporarytablename
// @nuget: Microsoft.EntityFrameworkCore.SqlServer
// @nuget: Z.EntityFramework.Extensions.EFCore
/*
## 🏷️ TemporaryTableName
Gets or sets the exact name to use for the temporary (or permanent) staging table.
If you provide a custom table name, you must also enable the option `TemporaryTableCreate = true;` if you want the library to **create** the table.
If you want the library to **create and drop** the table automatically afterward, you can simply use `TemporaryTableCreateAndDrop = true;`.
The name you choose determines the type of table that will be used:
* `"MyTemporaryTableName"` → uses a **permanent table**
* `"#MyTemporaryTableName"` → uses a **local temporary table**
* `"##MyTemporaryTableName"` → uses a **global temporary table**
You can use the string `{ZZZ_action}` in your name to have it automatically replaced by the current action (insert, update, delete, merge, synchronize).
### 💡 Why it can be useful
Using your own temporary table name can be very handy in different scenarios, such as:
* **Re-using the same table** across multiple operations instead of creating and dropping it every time.
* **Improving SQL query plan caching** since the optimizer can recognize the same table name and reuse execution plans.
* **Debugging and testing** by making the temporary table visible with a predictable name.
* **Coordinating across processes** (for example, with global temp tables) when different sessions need to share data.
*/
using System;
using System.Linq;
using System.Text;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
public class Program
{
public static void Main()
{
using (var context = new EntityContext())
{
context.Database.EnsureCreated();
CacheSchemaToIgnoreInLog(context);
}
using (var context = new EntityContext())
{
// minimum 11 customers to use a temporary table
var customers = GenerateCustomer(11);
StringBuilder sb = new StringBuilder();
context.BulkMerge(customers, options =>
{
options.TemporaryTableName = "#MyTemporaryTableName_{ZZZ_action}";
options.TemporaryTableCreateAndDrop = true;
options.Log = s => sb.AppendLine(s);
});
Console.WriteLine(sb.ToString());
FiddleHelper.WriteTable(context.Customers.AsNoTracking());
}
}
public static List<Customer> GenerateCustomer(int max)
{
var list = new List<Customer>();
for (int i = 0; i < max; i++)
{
list.Add(new Customer() { Name ="Customer_" + i});
}
return list;
}
public static void CacheSchemaToIgnoreInLog(EntityContext context)
{
var customers = GenerateCustomer(11);
context.BulkInsert(customers, options => { options.IsReadOnly = true; });
}
public class EntityContext : DbContext
{
public EntityContext()
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(new SqlConnection(FiddleHelper.GetConnectionStringSqlServer()));
base.OnConfiguring(optionsBuilder);
}
public DbSet<Customer> Customers { get; set; }
}
public class Customer
{
public int CustomerID { get; set; }
public string Name { get; set; }
public Boolean IsActive { get; set; }
}
}