[英]DbSet table name
要在實體框架 4.0 上獲取數據庫表名,我會:
ObjectSetInstance.EntitySet.ToString()
有沒有辦法在 Entity Framework 4.1 上做到這一點?
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 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.