如何从Entity Framework Core中的DbContext获取列名和相应的数据库类型

假设我有这个表:

在此处输入图像描述

如何从Entity Framework Core中的DbContext获取列名和数据库数据类型?

提示

  1. 名为clg#的列由EF Core Scaffold工具转换为clg1,因此我需要真正的列名而不是当前的EF名称

  2. 我需要数据库类型,而不是clrType,当然必须是跨平台。 也许我会改变数据库,所以方法也必须工作。

期望的结果:

      

谁能提供解决方案?

更新:从EF Core 2.0开始,情况发生了变化,因此原始答案不再适用。 现在EF Core为每种数据库类型构建单独的模型,因此代码更简单并直接使用Relational()扩展:

 var entityType = dbContext.Model.FindEntityType(clrEntityType); // Table info var tableName = entityType.Relational().TableName; var tableSchema = entityType.Relational().Schema; // Column info foreach (var property in entityType.GetProperties()) { var columnName = property.Relational().ColumnName; var columnType = property.Relational().ColumnType; }; 

原始答案(EF Core 1.x):

与EF相比,在EF Core中访问相关元数据要容易得多 – 从DbContext.Model属性开始获取IModel ,使用GetEntityTypesFindEntityType获取IEntityType ,然后使用GetPropertiesFindProperty获取IProperty等。

但问题是EF Core允许您对不同的目标数据库使用不同的设置。 为了获取与上下文使用的当前数据库相对应的属性,您需要访问IRelationalDatabaseProviderServices并使用AnnotationProviderTypeMapper属性来获取所需的信息。

这是一个例子:

 using System; using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Storage; public class DbColumnInfo { public string Name; public string Type; } public static class RelationalDbHelpers { public static IEnumerable GetDbColums(this DbContext dbContext, Type clrEntityType) { var dbServices = dbContext.GetService(); var relationalDbServices = dbServices.DatabaseProviderServices as IRelationalDatabaseProviderServices; var annotationProvider = relationalDbServices.AnnotationProvider; var typeMapper = relationalDbServices.TypeMapper; var entityType = dbContext.Model.FindEntityType(clrEntityType); // Not needed here, just an example var tableMap = annotationProvider.For(entityType); var tableName = tableMap.TableName; var tableSchema = tableMap.Schema; return from property in entityType.GetProperties() let columnMap = annotationProvider.For(property) let columnTypeMap = typeMapper.FindMapping(property) select new DbColumnInfo { Name = columnMap.ColumnName, Type = columnTypeMap.StoreType }; } }