2011-08-21 11 views
6

मैं अगले समस्या के लिए ठोकर खाई ... मैं डेटाबेस संदर्भ है:IQueryable <TEntity> का उपयोग बजाय <TEntity> समस्या DbSet

// For support unit testing... 
public interface IDbContext : IDisposable 
{ 
    IQueryable<Hardware> Hardwares { get; } 
    IQueryable<ProviderHardware> ProviderHardwares { get; } 
} 

// Real DbContext (EF 4.0, Code First) 
public class PrimaryDbContext : DbContext, IDbContext 
{ 
    public DbSet<Hardware> Hardwares { get; set; } 
    public DbSet<ProviderHardware> ProviderHardwares { get; set; } 

    IQueryable<Hardware> IDbContext.Hardwares 
    { get { return Hardwares; } } 
    IQueryable<ProviderHardware> IDbContext.ProviderHardwares 
    { get { return ProviderHardwares; } } 
    ... 
} 

और मैं सभी हार्डवेयर, जो नहीं करता है ProviderHardwares तालिका में मौजूद है कोशिश:

var hardwaresRemoved = db.Hardwares.Where(i => (i.IsAvailable == true) && 
    (db.ProviderHardwares.Count(j => j.Article == i.Article) == 0)).ToList(); 

यदि मैं प्राथमिक डीबीकॉन्टेक्स्ट का सख्ती से उपयोग करता हूं जैसे कि "PrimaryDbContext db = new PrimaryDbContext();" सब ठीक काम करते हैं। लेकिन अगर मैं इसे स्पष्ट रूप से उपयोग करता हूं "IDbContext db = new PrimaryDbContext();"

प्रकार 'ConfiguratorMvcApplication.DomainModels.ProviderHardware' की एक निरंतर मूल्य बनाने में असमर्थ: है कि मैं एक अपवाद मिलता है। केवल आदिम प्रकार (जैसे इंट 32, स्ट्रिंग, और ग्विड ') इस संदर्भ में में समर्थित हैं।

संक्षेप में प्रस्तुत करना, मैं एक IQueryable पर एक DbSet बदल नहीं सकते। और मैं इस मामले में यूनिट परीक्षण का उपयोग कैसे कर सकता हूं? मुझे आशा है कि किसी ने अभी तक इस समस्या का समाधान किया है ... अग्रिम धन्यवाद!

+0

क्या आप अपने 'प्राथमिक डीबीकॉन्टेक्स्ट' में कहीं भी निरंतर घोषणा कर रहे हैं? –

+0

नहीं, केवल यही है कि मैं पहले प्रदर्शित करता हूं ... और ऑनमोडेल क्रिएटिंग विधि को ओवरराइड करें ... – xtmq

+0

मैं इसे पुन: उत्पन्न कर सकता हूं। मैंने देखा (एसक्यूएल प्रोफाइलर के साथ) कि अभिव्यक्ति के अंदर 'आईडीबीकॉन्टेक्स्ट' केस 'डीबी.प्रोवाइडरहार्डवेयर' में एक क्वेरी के रूप में निष्पादित किया जाता है जो डेटाबेस से * सभी * 'प्रदाता हार्डवेयर 'पंक्तियों को लोड करता है (* जैसे *' आईडीबीकॉन्टेक्स्ट.प्रोवाइडरहार्डवेयर '' inumerable' थे और 'IQueryable' नहीं)। फिर 'गणना' और बाहरी क्वेरी निष्पादित नहीं की जा सकती क्योंकि ऑब्जेक्ट्स की स्मृति सूची ("निरंतर" ऑब्जेक्ट्स की सूची) का उपयोग SQL में नहीं किया जा सकता है। यह अपवाद का कारण बनता है। क्यों EF 'IDbContext.ProviderHardwares 'को' IENumerable' जैसा व्यवहार करता है लेकिन 'PrimaryDbContext.ProviderHardwares' नहीं? कोई सुराग नहीं ... – Slauma

उत्तर

-2

मैं सुझाव है कि आप बेहतर DbSets रखने के लिए और एकीकरण परीक्षणकरना डेटाबेस भी शामिल है।

क्योंकि, हालांकि डीबी के एक नकली के साथ एक यूनिट परीक्षण पास करना कुछ हद तक उपयोगी हो सकता है, तो आप वास्तविक डेटाबेस के साथ परीक्षण से बेहतर होने जा रहे हैं (लेकिन यह यूनिट परीक्षण नहीं है)।

कक्षा प्रारंभ में डेटाबेस मिटाएं और/या परीक्षण के लिए प्रारंभिक डेटा बनाएं।

यदि आप एक कनेक्शन स्ट्रिंग के साथ एक App.config फ़ाइल बनाते हैं तो आपके पास एक अलग परीक्षण डेटाबेस हो सकता है, और यदि आप ईएफ कोड का उपयोग कर रहे हैं, तो आप इसे मुफ्त में प्राप्त कर सकते हैं।

सर्वश्रेष्ठ संबंध।

+0

हाँ, मुझे लगता है कि आप सही हैं .. लेकिन मैं कोड में डेटाबेस कैसे बना और भर सकता हूं? मैं PrimaryDbContext में डोमेन ऑब्जेक्ट्स बना सकता हूं। क्या मैं डेटाबेस बना सकता हूं यह ऑब्जेक्ट्स स्थानीय एसक्यूएल सर्वर पर ईएफ कोड के माध्यम से स्वचालित रूप से स्वचालित रूप से हैं? और इसे अपने परीक्षणों में उपयोग करें? – xtmq

+0

हां, ईएफ कोड का उपयोग करके, डेटाबेस आपके ऐप को पहली बार बनाए और पॉप्युलेट कर सकता है, इस ट्यूटोरियल को जांचें: (http://www.asp.net/entity-framework/tutorials/creating-an-entity-framework डाटा मॉडल के लिए एक-एएसपी निवल MVC-आवेदन)। एक अतिरिक्त प्लस यह है कि यदि आप परीक्षण प्रोजेक्ट में App.config फ़ाइल बनाते हैं, तो आपको अपने विकास डेटाबेस के नि: शुल्क, अनिवार्य रूप से एक परीक्षण डेटाबेस मिलता है। मेरा सुझाव है कि आप SQL सर्वर कॉम्पैक्ट 4.0 का उपयोग करें। –

+0

धन्यवाद के, मैं इस मैनुअल को पढ़ने के लिए चल रहा हूँ =) – xtmq

1

मैं प्रत्येक डीबीसेट के लिए दो गुणों को समाप्त करता हूं: एक प्रकार का IQueryable, और एक प्रकार का डीबीसेट। IQueryable संपत्ति इंटरफ़ेस में परिभाषित किया गया है, और यह ठोस कार्यान्वयन (प्रकार DbSet की संपत्ति) के लिए कॉल रिले, इस प्रकार है:

// Exists in the interface 
public IQueryable<AccountContact> AccountContacts 
{ 
    get 
    { 
     return DbAccountContacts; 
    } 
    set 
    { 
     DbAccountContacts = (DbSet<AccountContact>)value; 
    } 
} 

// Exists only in the implementation 
public DbSet<AccountContact> DbAccountContacts { get; set; } 

इस स्थापना के बाद, मैं सही ढंग से काम करने के लिए मजाक प्राप्त करने में सक्षम था और इकाई कोड का परीक्षण कर सकता है।

यह ओपी के लिए निश्चित रूप से बहुत देर हो चुकी है, लेकिन हो सकता है कि यह किसी ऐसे प्रश्न की सहायता करे जो मेरे जैसा ही है।

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