2010-10-08 22 views
17

यही है। यह बहुत आसान है। मुझे एक एडीएमएक्स मिला है और मैं इसे टेबल के लिए गतिशील रूप से पूछताछ करने में सक्षम होना चाहता हूं और (उम्मीद है), गतिशील रूप से उस तालिका के खिलाफ निर्माण करना चाहता हूं। क्या यह संभव है?इकाई फ्रेमवर्क - टेबल्स की सूची प्राप्त करें

=========

अद्यतन:

मैं सभी डीबी टेबल, लेकिन कोई विचार या सपा के संदर्भ में शामिल किया है। हमारे पास बहुत सारी टेबल हैं जो जानकारी टाइप करती हैं (आईडी के साथ)। तो, उदाहरण के लिए, रंग या फ़ाइल प्रकार या प्रोटोकॉल प्रकार। मैं उन टेबलों के लिए एक प्रकार (फ़ाइल) क्वेरी लेने में सक्षम होना चाहता हूं जो टाइप जानकारी (फ़ाइल, फ़ाइल टाइप) धारण कर सकते हैं और इसे आईडी के साथ वापस कर सकते हैं।

तो, मैं देख सकता हूं ... बिजनेस यूनिट (या रंग, या फ़ाइल) और कोड बंद हो जाएगा और BusinessUnit (या रंग या फ़ाइल) और BusinessUnitType (या ColorType या FileType) के संदर्भ को खोजेगा। यदि यह किसी एक को पाता है, तो यह पूछताछ करेगा और सभी पंक्तियों को वापस कर देगा ताकि मैं देख सकूं कि इसमें प्रकार की जानकारी है या नहीं (मैं इसे बाद में आईडी और विवरण, संक्षेप या नाम फ़ील्ड के साथ-साथ पंक्तियों को सीमित करने के लिए परिष्कृत कर दूंगा) और किसी भी विशेष के लिए संबंधित आईडी को खोजने में सक्षम हो।

+2

टेबल्स या संस्थाओं से यह नमूना कोड? सार या ठोस? नाम या प्रकार? क्यूं कर? कृपया विशिष्ट रहें। –

+0

टेबल्स - यही वह है। बस टेबल एसक्यूएल सर्वर में sysobjects पूछताछ करके आप जिस तरह की चीज प्राप्त करेंगे। – Michael

+0

क्या आप अपने संदर्भ में या डीबी में टेबल चाहते हैं? – Nix

उत्तर

13

डेटाबेस में तालिकाओं को गिनने के तरीके पर आपके पहले प्रश्न के लिए, यह कोड उन्हें आपके लिए प्राप्त करेगा, निश्चित रूप से वे आपके ईडीएम में आयात किए गए हैं जो आपके डेटा स्टोर में सभी टेबल नहीं हैं।

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

इस कोड को इस संदेश के साथ एक InvalidOperationException कारण होगा:
अंतरिक्ष 'SSpace' नहीं जुड़े संग्रह
है और वह क्योंकि CSpace, SSpace (SSDL) के विपरीत लोड नहीं है यह है जब तक है जरूरत है। और मेटाडाटा वर्कस्पेस के साथ उन्हें पढ़ने की कोशिश कर रहा है, इसकी आवश्यकता नहीं है। क्वेरी संकलन के दौरान, फिर ऑब्जेक्ट भौतिकरण पर इसकी आवश्यकता होती है। इसलिए मेटाडाटा वर्कस्पेस को हमारे लिए लोड करने के लिए इसे चालित करने के लिए हमें मुख्य क्वेरी चलाने से पहले नीचे की तरह एक क्वेरी चलाने की आवश्यकता है जो हमें टेबल नाम देता है।

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

आप यहाँ से अधिक पढ़ सकते हैं: Quick Trick for forcing MetadataWorkspace ItemCollections to load

हालांकि, अगर आपका इरादा अपने प्रकार टेबल के खिलाफ एक गतिशील क्वेरी बनाने के लिए है, तो आप SSpace के साथ चारों ओर गंदगी की जरूरत नहीं है, आप के लिए है इसे सीएसपीएएस (अवधारणात्मक मॉडल) से प्राप्त करें।

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; 
    } 
} 


कोड स्पष्टीकरण:: मेरे धारणा गया था कि अपने प्रकार तालिका नाम में "प्रकार" समाप्त हो जाती नीचे दिए गए तालिका नाम का केवल एक हिस्सा होने के साथ एक गतिशील क्वेरी बनाने के लिए पर एक नमूना कोड है एक पोस्टफिक्स (जैसे कलरटाइप) के रूप में, ताकि आप GetAllType ("रंग") पर कॉल कर सकें और यह आपके मॉडल में ColorType EntityObject की खोज करे और आपको सभी संभावित मान देगा। कोड डरावना लग सकता है लेकिन यह बहुत आसान सामान है। असल में यह सब कुछ है कि यह विधि पैरामीटर के आधार पर मेटाडेटा (जैसे एंटीटीसेट नाम, नेमस्पेस नाम, आदि ...) से सभी आवश्यक जानकारी प्राप्त करता है और फिर फ्लाई पर एक EntitySQL क्वेरी का निर्माण करता है, फिर इसे निष्पादित करता है और वापस लौटाता है परिणाम है।

+2

उपरोक्त कोड का क्या ईएफ संस्करण कृपया? मैंने EF4.0 में कोशिश की, और "t => t.Name" संकलित भी नहीं करता है। कोई समाधान? –

+0

मैं ईएफ 6.1.1 का उपयोग कर रहा हूं और यह कोड मेरे लिए काम करता है tableList = db.MetadataWorkspace.GetItems (डेटास्पेस.एससी स्पेस)। चयन करें (x => x.Name); –

+0

मुझे @LeiYang की एक ही समस्या है: var items = objectContext.MetadataWorkspace.GetItems (DataSpace.SSpace); – Evilripper

2

बस अगर यह मदद करता है, तो मैंने इन्हें ऑब्जेक्ट कॉन्टेक्स्ट एक्स्टेंशन क्लासेस में से एक से खींच लिया।

आप अपने ऑब्जेक्ट संदर्भ से पूछ सकते हैं और नीचे दिए गए नाम प्राप्त कर सकते हैं। हालांकि आप इसे संशोधित करने के लिए स्वतंत्र महसूस करें।

public static class ObjectContextExtensions 
{ 
    public static string GetEntitySetName<T>(this ObjectContext theContext, T eo) where T : EntityObject 
    { 
     string entitySetName = ""; 
     if (eo.EntityKey != null) 
     { 
      entitySetName = eo.EntityKey.EntitySetName; 
     } 
     else 
     { 
      string className = typeof(T).Name; 
      var container = 
        theContext.MetadataWorkspace.GetEntityContainer(theContext.DefaultContainerName, DataSpace.CSpace); 
      entitySetName = (from meta in container.BaseEntitySets 
          where meta.ElementType.Name == className 
          select meta.Name 
          ).First(); 

     } 

     return entitySetName; 
    } 
    public static IEnumerable<EntitySetBase> GetEntitySets(this ObjectContext theContext) 
    { 
      var container = 
        theContext.MetadataWorkspace 
         .GetEntityContainer(
          theContext.DefaultContainerName, 
          DataSpace.CSpace); 

      return container.BaseEntitySets; 
    } 
    public static IEnumerable<ObjectQuery> GetObjectQueries(this ObjectContext theContext) 
    { 
     IEnumerable<ObjectQuery> queries = 
       from pd in theContext 
          .GetType() 
          .GetProperties() 
       where pd.PropertyType 
         .IsSubclassOf(typeof(ObjectQuery)) 
       select (ObjectQuery)pd.GetValue(theContext, null); 
     return queries; 
    } 
} 

जब आप इसका इस्तेमाल करते हैं:

IEnumerable<EntitySetBase> lookAtMe = context.GetEntitySets(); 
//ElementType (type of entity the set represents) 
//Entity Set Name 
//Other fun goodies ;) 

//Example of how to get the entity set to query on it. 
File f = new File(); 
//or some entity you selected. 
f = context.Files.FirstOrDefault(); 
string name = context.GetEntitySetName(f); 

एक दूसरे मैं बाहर छोड़ दिया GetObjectQueries था और यह सिर्फ ObjectQueries, जो आपके संदर्भ में चीजें हैं जो आप पर क्वेरी कर रहे हैं के सभी देता है । संदर्भ। कुछ योग्य या संदर्भ। उत्पाद।

मुझे यकीन नहीं है कि आप क्या कर रहे हैं, इसलिए ऐसा करने का एक बेहतर तरीका हो सकता है .... एक बार जब आप अपना अंतिम लक्ष्य अपडेट कर लेंगे तो मैं तदनुसार संपादित करूँगा।

10

पद What Tables Are In My EF Model? And My Database?

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); 
    } 
} 
+1

यह पूर्णतम समाधान – netfed

+1

है ... और यदि आप टेबल/इकाइयों के गुण/फ़ील्ड सूचीबद्ध करना चाहते हैं, तो आप टेबल ऑब्जेक्ट से पूछ सकते हैं: var PropertiesInTables = tables.Select (s => s.ElementType.Properties) ।सूची बनाने के लिए(); – netfed

संबंधित मुद्दे