【发布时间】:2018-01-21 20:32:30
【问题描述】:
由于某种原因,我需要在 EFCore 中使用 SQL,我将使用映射实体的表名。我怎样才能得到它?
【问题讨论】:
标签: asp.net-core .net-core entity-framework-core
由于某种原因,我需要在 EFCore 中使用 SQL,我将使用映射实体的表名。我怎样才能得到它?
【问题讨论】:
标签: asp.net-core .net-core entity-framework-core
在 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://docs.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); }
IEntityType 还有一个扩展方法。所以entityType.GetTableName()
entityType.GetSchemaQualifiedTableName()。手动创建查询可能很有用。
你可以使用这个静态类
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 "现在允许将实体类型同时映射到表和视图"。
我不完全理解这一点,但它增加了查找表名的复杂性。
对于我的用例,我实际上想要视图的名称,因此通过检查 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");
}
【讨论】:
按照西蒙的回答。在 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" />
【讨论】:
从 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();
【讨论】: