如何在Entity Framework Core中获取映射实体的表名

77

由于某些原因,我需要在EFCore中使用SQL,并且将使用映射实体的表名。我该如何获取它?


似乎这可以工作。 - Andrew Cui
5个回答

137

使用2.X版本中的Microsoft.EntityFrameworkCore.Relational软件包:

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();

这个代码可以获取所有表名吗?`var modelNames = context.Model.GetEntityTypes(); foreach (var modelName in modelNames) { Console.WriteLine(modelName.Name); }` - Allen Wang
2
此外,IEntityType 还有一个扩展方法可用。因此,可以使用 entityType.GetTableName() - momvart
2
有一个新的扩展方法,可以提供以模式名称为前缀的表名:entityType.GetSchemaQualifiedTableName()。它可能有助于手动创建查询。 - MÇT

5
你可以使用这个静态类。
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类获取People。
var TblName= AttributeReader.GetTableName<YourModel>(YourContext);

4

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

1

继续Simon的答案。在EF Core 5x版本中,可以使用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" />

0

获取架构名称的 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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接