How to get Column name and corresponding Database Type from DbContext in Entity Framework Core

前端 未结 3 1328
臣服心动
臣服心动 2020-12-01 21:10

Suppose I have this table:

How can I get the column name and database datatype from DbContext in Entity Framework Core?

Tips

3条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-01 21:38

    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)")
    
    

提交回复
热议问题