繁体   English   中英

数据库集表名

[英]DbSet table name

要在实体框架 4.0 上获取数据库表名,我会:

ObjectSetInstance.EntitySet.ToString()

有没有办法在 Entity Framework 4.1 上做到这一点?

DbContextObjectContext的扩展方法:

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 object:

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

使用 DbContext object:

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

更多信息在这里:

实体框架:从实体获取映射表名

从 EF6.1 开始, 本文探讨的解决方案展示了如何使用新公开的元数据来完成此操作,不应该要求初始化数据库或依赖于使用什么方法来设置表名。

尝试这样的事情:

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

你可以尝试这样的事情。

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

请参阅以下链接以获取更多信息。 关联

我还发现 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()的问题 - 缺少一个解决数据库模式的步骤)。

您可以应用扩展方法从您的实体 class 获取表名
在这种情况下,您不需要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();

资料来源: 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));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM