C# 数据库集表名

C# 数据库集表名,c#,entity-framework-4.1,C#,Entity Framework 4.1,要在Entity framework 4.0上获取数据库表名,我需要: ObjectSetInstance.EntitySet.ToString() 在EntityFramework4.1上有这样做的方法吗?您可以尝试类似的方法 private string GetTableName(Type type) { var tableAttribute = type.GetCustomAttributes(false).OfType<System.ComponentModel.DataAn

要在Entity framework 4.0上获取数据库表名,我需要:

ObjectSetInstance.EntitySet.ToString()

在EntityFramework4.1上有这样做的方法吗?

您可以尝试类似的方法

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());
请参阅下面的链接了解更多信息。

试试这样的方法:

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

用于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;
    }
}
公共静态类contextensions
{
公共静态字符串GetTableName(此DbContext上下文),其中T:class
{
ObjectContext=((IOObjectContextAdapter)context).ObjectContext;
返回objectContext.GetTableName();
}
公共静态字符串GetTableName(此ObjectContext上下文),其中T:class
{
字符串sql=context.CreateObjectSet().ToTraceString();
正则表达式正则表达式=新正则表达式(“从(?.*)作为”);
Match=regex.Match(sql);
string table=match.Groups[“table”].Value;
返回表;
}
}
使用ObjectContext对象:

ObjectContext context = ....;
string table = context.GetTableName<Foo>();
DbContext context = ....;
string table = context.GetTableName<Foo>();
ObjectContext=。。。。;
string table=context.GetTableName();
使用DbContext对象:

ObjectContext context = ....;
string table = context.GetTableName<Foo>();
DbContext context = ....;
string table = context.GetTableName<Foo>();
DbContext上下文=。。。。;
string table=context.GetTableName();
更多信息请点击此处:


我还发现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 GetEntitySet(DbContext上下文) { var类型=类型(T); var entityName=type.Name; 变量元数据=((IObjectContextAdapter)上下文).ObjectContext.MetadataWorkspace; IEnumerable实体集; entitySets=metadata.GetItemCollection(DataSpace.SSpace) .GetItems() .Single() .BaseEntitySets 第()类 .Where(s=>!s.MetadataProperties.Contains(“类型”) ||s.MetadataProperties[“Type”].ToString()=“Tables”); var entitySet=entitySets.FirstOrDefault(t=>t.Name==entityName); 返回实体集; }
为了获取表名,我使用了另外两种方法代替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;
}
公共字符串GetTableName(DbContext上下文)
T:在哪里上课
{
var entitySet=GetEntitySet(上下文);
if(entitySet==null)
抛出新异常(“无法在edm元数据.F(typeof(T).Name)中找到实体集“{0}”);
var tableName=GetStringProperty(entitySet,“Schema”)+“+GetStringProperty(entitySet,“Table”);
返回表名;
}
私有字符串GetStringProperty(MetadataItem entitySet,string propertyName)
{
元数据属性;
if(entitySet==null)
抛出新ArgumentNullException(“entitySet”);
if(entitySet.MetadataProperties.TryGetValue(propertyName、false、out属性))
{
字符串str=null;
if(((属性!=null)&&
(property.Value!=null))&&
((str=property.Value作为字符串)!=null)&&
!string.IsNullOrEmpty(str)))
{
返回str;
}
}
返回字符串。空;
}
这将返回数据库中使用的实际名称以及db模式(如果您不使用dbo),并且应与数据注释或fluent配置一起使用

唯一的警告可能是数据库应该已经初始化。(我认为这就是使用CreateObjectSet()的问题所在。-缺少解决db模式的步骤)。

来源:

使用System.Data.Entity;
使用System.Data.Entity.Infrastructure.DependencyResolution;
使用系统、数据、实体、基础设施、多元化;
var service=DbConfiguration.DependencyResolver.GetService();
var entitySetName=service.Pluralize(typeof(tenty.Name));

从EF6.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;
}
用法:

var tableName = entity.GetTableName();

如果您使用fluent映射
ToTable
而不是
Table
属性,该怎么办?我的entityTrue上没有TableAttribute,这不会获取fluent版本,但我尝试了上面的“EntitySet.Name”解决方案,但似乎两者都没有。这对我不起作用-它不会获取我设置的Table属性,它只返回类的复数名称。它也不能获取流畅的更改。降级太快,将在7分钟内重新发布。在EF6.x中对我有效。这很慢。我在
return objectContext.GetTableName()行上为namesI get“无法解析符号'GetTableName'”添加了一个缓存DbContext
版本中的code>。@ProfK:扩展方法是否在同一个类中?不,它们与我的所有扩展一样在扩展类中。我不能使我的DbContext类成为静态。@ProfK:对不起,我不明白你想说什么。。。。为什么要将DbContext类设置为静态?我没有。我想你是说我的DbSet在同一个类中有扩展方法吗。我的错。这不使用配置,相反,它只假设默认约定。当手动重写表名、不使用复数约定或使用自定义命名约定时,这不起作用。