C# 数据库集表名
要在Entity framework 4.0上获取数据库表名,我需要: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
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;
用于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;
}
}
公共静态类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在同一个类中有扩展方法吗。我的错。这不使用配置,相反,它只假设默认约定。当手动重写表名、不使用复数约定或使用自定义命名约定时,这不起作用。