DbSet表名

时间:2011-07-06 15:21:28

标签: c# entity-framework-4.1

要在Entity framework 4.0上获取数据库表名,我会这样做:

ObjectSetInstance.EntitySet.ToString()

有没有办法在Entity Framework 4.1上执行此操作?

7 个答案:

答案 0 :(得分:24)

DbContext ObjectContext 的扩展方法:

public static class ContextExtensions
{
    public static string GetTableName<T>(this DbContext context) where T : class
    {
        ObjectContext objectContext = ((IObjectContextAdapter) context).ObjectContext;

        return objectContext.GetTableName<T>();
    }

    public static string GetTableName<T>(this ObjectContext context) where T : class
    {
        string sql = context.CreateObjectSet<T>().ToTraceString();
        Regex regex = new Regex("FROM (?<table>.*) AS");
        Match match = regex.Match(sql);

        string table = match.Groups["table"].Value;
        return table;
    }
}

使用ObjectContext对象:

ObjectContext context = ....;
string table = context.GetTableName<Foo>();

使用DbContext对象:

DbContext context = ....;
string table = context.GetTableName<Foo>();

更多信息:

Entity Framework: Get mapped table name from an entity

答案 1 :(得分:5)

从EF6.1开始,在this文章中探讨的解决方案展示了如何使用新暴露的元数据来实现这一点,不应该要求初始化数据库或者取决于使用什么方法来设置表名。

答案 2 :(得分:4)

尝试这样的事情:

string name = (context as IObjectContextAdapter).ObjectContext.CreateObjectSet<MyClass>().EntitySet.Name;

答案 3 :(得分:3)

你可以尝试这样的事情。

private string GetTableName(Type type)
{
  var tableAttribute = type.GetCustomAttributes(false).OfType<System.ComponentModel.DataAnnotations.TableAttribute>().FirstOrDefault();
  return tableAttribute == null ? type.Name : tableAttribute.Name;
}

您可以像这样调用此字符串。

var tableName = GetTableName(entityType.FirstOrDefault());

有关详细信息,请参阅以下链接。 Link

答案 4 :(得分:1)

我还发现CreateObjectSet()并不能完成这项工作,特别是在获取用于SqlBulCopy()的列名时。 以下用于获取EntitySet的代码似乎更好,

 private EntitySet GetEntitySet<T>(DbContext context)
{
    var type = typeof(T);
    var entityName = type.Name;
    var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace;

    IEnumerable<EntitySet> entitySets;
    entitySets = metadata.GetItemCollection(DataSpace.SSpace)
                     .GetItems<EntityContainer>()
                     .Single()
                     .BaseEntitySets
                     .OfType<EntitySet>()
                     .Where(s => !s.MetadataProperties.Contains("Type")
                                 || s.MetadataProperties["Type"].ToString() == "Tables");
    var entitySet = entitySets.FirstOrDefault(t => t.Name == entityName);
    return entitySet;
}

要获取表名,我使用了另外两种方法,而不是 EntitySet.Name ,它返回单数而不是复数的名称。

public string GetTableName<T>(DbContext context)
            where T: class
{
    var entitySet= GetEntitySet<T>(context);
    if (entitySet == null)
        throw new Exception("Unable to find entity set '{0}' in edm metadata".F(typeof(T).Name));
    var tableName = GetStringProperty(entitySet, "Schema") + "." + GetStringProperty(entitySet, "Table");
    return tableName;
}

private string GetStringProperty(MetadataItem entitySet, string propertyName)
{
    MetadataProperty property;
    if (entitySet == null)
        throw new ArgumentNullException("entitySet");
    if (entitySet.MetadataProperties.TryGetValue(propertyName, false, out property))
    {
        string str = null;
        if (((property != null) &&
            (property.Value != null)) &&
            (((str = property.Value as string) != null) &&
            !string.IsNullOrEmpty(str)))
        {
            return str;
        }
    }
    return string.Empty;
}

这将返回数据库中使用的实际名称以及db模式(如果您不使用dbo),并且应该使用数据注释或流畅配置。

唯一需要注意的是数据库应该已经初始化了。 (我认为使用 CreateObjectSet()的问题 - 缺少一个解决db模式的步骤。)

答案 5 :(得分:1)

来源:https://msdn.microsoft.com/en-gb/data/jj819164.aspx

using System.Data.Entity;
using System.Data.Entity.Infrastructure.DependencyResolution;
using System.Data.Entity.Infrastructure.Pluralization;

var service = DbConfiguration.DependencyResolver.GetService<IPluralizationService>();
var entitySetName = service.Pluralize(typeof(TEntity).Name));

答案 6 :(得分:1)

您可以应用扩展方法从实体类中获取表名
在这种情况下,您不需要 DbContext 来获取表名,它会在扩展方法中获取它

public static string GetTableName<T>(this T entity) where T : class
{
    var object_context = GetObjectContext(entity);

    if (object_context == null || object_context.TransactionHandler == null)
        return null;

     var dbcontext=object_context.TransactionHandler.DbContext;
    var query= dbcontext.Set(entity.GetType()).ToString();
    var reg = new Regex(@"FROM \[dbo\]\.\[(?<table>.*)\] AS");
    var match = reg.Match(query);

    var tableName= match.Groups["table"].Value;
    return tableName;
}

private static ObjectContext GetObjectContext(object entity)
{
    var field = entity.GetType().GetField("_entityWrapper");

    if (field == null)
        return null;

    var val= field.GetValue(entity);
    var property = val.GetType().GetProperty("Context");
    var context = (ObjectContext)property.GetValue(val, null);

    return context;
}

这是我们到达 DbContext 的地方:

var object_context = GetObjectContext(entity)

用法:

var tableName = entity.GetTableName();