簡體   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