如何获得实体框架核心映射实体的表名称

由于某种原因,我需要在 EFCore 中使用 SQL,我将使用映射实体的表名。我怎样才能得到它?

40904 次浏览

在2.X 中使用 微软。实体框架核心。关系包:

var mapping = dbContext.Model.FindEntityType(typeof(YourEntity)).Relational();
var schema = mapping.Schema;
var tableName = mapping.TableName;

这里假设 dbContext是从 DbContext继承的类的实例,并且您在那里配置了 YourEntity

请注意,在 EF Core 3.X 中,[ .Relational()提供程序扩展已被](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#provider)替换为 getter,因此您现在可以按照以下方式访问模式:

var entityType = dbContext.Model.FindEntityType(typeof(YourEntity));
var schema = entityType.GetSchema();
var tableName = entityType.GetTableName();

您可以使用这个静态类

public static class AttributeReader
{
//Get DB Table Name
public static string GetTableName<T>(DbContext context) where T : class
{
// We need dbcontext to access the models
var models = context.Model;


// Get all the entity types information
var entityTypes = models.GetEntityTypes();


// T is Name of class
var entityTypeOfT = entityTypes.First(t => t.ClrType == typeof(T));


var tableNameAnnotation = entityTypeOfT.GetAnnotation("Relational:TableName");
var TableName = tableNameAnnotation.Value.ToString();
return TableName;
}


}

例如,我们有 Person 类,数据库中的实体名称是 People,我们可以从 Person 类中获取人。

var TblName= AttributeReader.GetTableName<YourModel>(YourContext);

EF Core 5版本

EF Core 5 “现在允许同时将一个实体类型映射到一个表和一个视图”。

我不理解 完全,但它增加了寻找表名的复杂性。

对于我的用例,我实际上需要一个视图的名称,所以通过检查 TableName 和 ViewName,如果提供的实体的类型不对,我可以抛出一个错误。

var entityType = typeof(Customer);
var modelEntityType = context.Model.FindEntityType(entityType);


string tableName = modelEntityType.GetSchemaQualifiedTableName();
string viewName = modelEntityType.GetSchemaQualifiedViewName();


if (tableName != null)
{
throw new Exception("The Entity " + entityName + " represents a table and not a view");
}

接下来是西蒙的回答。在 EFCoreVersion5x 中,可以使用 Microsoft 扩展方法。创建了一个 DbContext助手扩展方法:

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;


public static class EfCoreExtensions
{
public static string GetSchemaQualifiedTableName(this DbContext context, Type entityType)
{
IEntityType et = context.Model.FindEntityType(entityType);
//what to do here, entity could be both view and table!?
//string viewName = et.GetSchemaQualifiedViewName();
return et.GetSchemaQualifiedTableName();
}
}

这样使用的例子:

  string tableName = _dbContext.GetSchemaQualifiedTableName(typeof(SomeEntity));

MS 扩展方法被安置在类中:

Microsoft.EntityFrameworkCore.RelationalEntityTypeExtensions

使用 Nuget引用

<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.4" />

获取架构名称的 DbSet 扩展方法

根据 Rax 的扩展方法,您可以直接从 DBSet 编写一个扩展方法,如下所示:

    /// <summary>
/// Gets the Schema Table name for the DbSet.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dbSet"></param>
/// <returns></returns>
public static string GetTableSchemaName<T>(this DbSet<T> dbSet) where T : class
{
var context = dbSet.GetService<ICurrentDbContext>().Context;
var entityType = typeof(T);
var m = context.Model.FindEntityType(entityType);


return m.GetSchemaQualifiedTableName();
}

用法如下:

var context = new SystemContext();
var name = context.SystemTable.GetTableSchemaName();