Suppose I have this table:
How can I get the column name and database datatype from DbContext
in Entity Framework Core?
Tips
Based on EFC3.1 answer I have created this helper to store all table names and column names into an dictionaries of a singleton populated on first use so the code doesn't have to traverse everything again and again. We use it for NPGSQL bulk copy operations and it seems to work properly. This version does not filter out any properties from entity classes so be careful about ordering of fields when doing column name lists/strings. But then again as I understand it, you will get only properties that are mapped in context so everything might be ok.
The helper
public class ContextHelper
{
private readonly ILogger logger;
private readonly ApplicationDbContext context;
private static Dictionary tableNames = new Dictionary(30);
private Dictionary> columnNames = new Dictionary>(30);
public ContextHelper(ILogger logger, ApplicationDbContext context)
{
this.logger = logger;
this.context = context;
PopulateTableNames();
PopulateColumnNames();
}
private void PopulateTableNames()
{
logger.LogInformation("Populating table names in context helper");
foreach (var entityType in context.Model.GetEntityTypes())
{
tableNames.Add(entityType.ClrType, entityType.GetTableName());
}
}
private void PopulateColumnNames()
{
logger.LogInformation("Populating column names in context helper");
foreach (var entityType in context.Model.GetEntityTypes())
{
var clrType = entityType.ClrType;
if (!columnNames.ContainsKey(clrType))
{
columnNames.Add(clrType, new Dictionary(30));
}
foreach (var property in entityType.GetProperties())
{
columnNames[clrType].Add(property.Name, property.GetColumnName());
}
}
}
public string GetTableName()
{
return context.Model.FindEntityType(typeof(T)).GetTableName();
}
public string GetColumnName(string propertyName)
{
return columnNames[typeof(T)][propertyName];
}
public List GetColumnNames()
{
return columnNames[typeof(T)].Select(x => x.Value).ToList();
}
}
Startup registration
services.AddSingleton();
Usage, something along these lines
var columnNames = contextHelper.GetColumnNames().Where(x=>x != contextHelper.GetColumnName(nameof(OvenEventLog.IdLog)));
var separatedCN = string.Join(", ", columnNames);
using (var writer = conn.BeginBinaryImport(
$"COPY {contextHelper.GetTableName()} ({separatedCN}) FROM STDIN (FORMAT BINARY)")