實體框架 - 獲取表列表

entity-framework

而已。這很簡單。我有一個edmx,並希望能夠動態地查詢表和(希望)動態構建該表。那可能嗎?

=========

更新:

我在上下文中包含了所有數據庫表,但沒有包含視圖或SP。我們有很多類型信息的表(帶有id)。因此,例如,顏色或文件類型或協議類型。我希望能夠對可能包含類型信息(File,FileType)的表進行類型(文件)查詢,並使用id返回它。

因此,我可能會尋找...業務單位(或顏色或文件),代碼將關閉並蒐索BusinessUnit(或顏色或文件)和BusinessUnitType(或ColorType或FileType)的上下文。如果它找到任何一個,它將查詢它並將返回所有行,以便我可以看到它是否包含類型信息(我稍後將其細化為僅返回ID和描述,縮寫或名稱字段以及限制行等)並能夠找到特定任何東西的相關ID。

一般承認的答案

關於如何枚舉數據庫中的表的第一個問題,這段代碼將為您提供這些代碼,當然這些代碼已經導入到您的EDM中,而EDM並不是數據存儲中的所有表。

var tableNames = context.MetadataWorkspace.GetItems(DataSpace.SSpace)
                        .Select(t => t.Name)
                        .ToList();

此代碼將導致帶有以下消息的InvalidOperationException:
空間'SSpace'沒有關聯的集合
這是因為與CSpace不同,SSpace(ssdl)在需要之前不會加載。並嘗試使用MetadataWorkspace讀取它們並不算是必需的。在查詢編譯期間需要它,然後在對象實現時再次需要它。因此,為了欺騙MetadataWorkspace為我們加載它,我們需要在運行提供表名的主查詢之前運行如下所示的查詢。

string temp = ((ObjectQuery)context.[EntitySetName]).ToTraceString();

您可以從此處閱讀更多內容: 強制要求加載MetadataWorkspace ItemCollections的快速操作

但是,如果您打算針對類型表構建動態查詢,那麼您不需要使用SSpace,您必須從CSpace(概念模型)獲取它。下面是一個示例代碼,介紹如何構建只包含表名的一部分的動態查詢:

ObjectResult<DbDataRecord> GetAllTypes(string name) {
    using (TypeEntities context = new TypeEntities()) {

    MetadataWorkspace metadataWorkspace = context.MetadataWorkspace;
    EntityContainer container = metadataWorkspace.GetItems<EntityContainer>
                                                      (DataSpace.CSpace).First();
    string namespaceName = metadataWorkspace.GetItems<EntityType>
                                        (DataSpace.CSpace).First().NamespaceName;

    string setName = string.Empty;
    string entityName = name + "Type";

    EntitySetBase entitySetBase = container.BaseEntitySets
            .FirstOrDefault(set => set.ElementType.Name == entityName);

    if (entitySetBase != null) {
        setName = entitySetBase.Name;
    }
    EntityType entityType = metadataWorkspace
         .GetItem<EntityType>(namespaceName + "." + entityName, DataSpace.CSpace);

    StringBuilder stringBuilder = new StringBuilder().Append("SELECT entity ");
    stringBuilder
       .Append(" FROM " + container.Name.Trim() + "." + setName + " AS entity ");
    string eSQL = stringBuilder.ToString();

    ObjectQuery<DbDataRecord> query = context.CreateQuery(eSQL);
    ObjectResult<DbDataRecord> results = query.Execute(MergeOption.AppendOnly);
    return results;
    }
}


代碼說明:我的假設是您的類型表名稱以“Type”結尾作為後綴(例如ColorType),因此您可以調用GetAllType(“Color”)並在模型中搜索ColorType EntityObject並將為您提供所有可能的價值觀代碼可能看起來很嚇人,但這很簡單。基本上它所做的就是它根據方法參數從MetaData獲取所有必需的信息(如EntitySet名稱,命名空間名稱等),然後動態構建一個EntitySQL查詢,然後執行它並返回結果。


熱門答案

此示例代碼來自哪些表格在我的EF模型中?和我的數據庫?

using (var dbContext = new YourDbContext())
{
    var metadata = ((IObjectContextAdapter)dbContext).ObjectContext.MetadataWorkspace;

    var tables = metadata.GetItemCollection(DataSpace.SSpace)
        .GetItems<EntityContainer>()
        .Single()
        .BaseEntitySets
        .OfType<EntitySet>()
        .Where(s => !s.MetadataProperties.Contains("Type")
        || s.MetadataProperties["Type"].ToString() == "Tables");

    foreach (var table in tables)
    {
        var tableName = table.MetadataProperties.Contains("Table")
            && table.MetadataProperties["Table"].Value != null
            ? table.MetadataProperties["Table"].Value.ToString()
            : table.Name;

        var tableSchema = table.MetadataProperties["Schema"].Value.ToString();

        Console.WriteLine(tableSchema + "." + tableName);
    }
}


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因