Entity Framework Data Context कैसे पढ़ें


112

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


3
उन्हें एक उपयोगकर्ता के साथ एक संदर्भ दें जिसमें डेटाबेस तक पहुंच नहीं है।
vcsjones

धन्यवाद। एक SQLite डेटाबेस का उपयोग कर Im। बस पता चला है कि इसे कनेक्शन स्ट्रिंग विकल्प के माध्यम से आसानी से खोला जा सकता है।
हरिन्दाका

2
उन्हें एक मत दो DbContext, उन्हें एक IQueryableया कई दो।
ta.speot.is

जवाबों:


178

केवल-पढ़ने वाले उपयोगकर्ता के साथ जुड़ने के अलावा, कुछ अन्य चीजें हैं जो आप अपने DbContext से कर सकते हैं।

public class MyReadOnlyContext : DbContext
{
    // Use ReadOnlyConnectionString from App/Web.config
    public MyContext()
        : base("Name=ReadOnlyConnectionString")
    {
    }

    // Don't expose Add(), Remove(), etc.
    public DbQuery<Customer> Customers
    {
        get
        {
            // Don't track changes to query results
            return Set<Customer>().AsNoTracking();
        }
    }

    public override int SaveChanges()
    {
        // Throw if they try to call this
        throw new InvalidOperationException("This context is read-only.");
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // Need this since there is no DbSet<Customer> property
        modelBuilder.Entity<Customer>();
    }
}

1
यह स्पष्ट था कि आप एक 'आदमी के अंदर' हैं :) - यह '
रीडऑनली

6
ध्यान दें कि उपयोग AsNoTracking()करने से आलसी लोडिंग का उपयोग करना असंभव हो जाएगा।
टॉम पैज़ोउरेक

@ TomPažourek मुझे नहीं पता कि क्या यह सच है ... मुझे लगता है कि EF अभी भी आलसी-लोडिंग परदे के पीछे बनाता है, लेकिन पहचान संकल्प थोड़ा अजीब हो सकता है।
ब्रिकेलम

3
public override Task<int> SaveChangesAsync()साथ ही ओवरराइड करना न भूलें ।
पीट

7
इस पर भरोसा मत करो, क्योंकि (context as IObjectContextAdapter).ObjectContext.SaveChanges()अभी भी काम करेगा। सबसे अच्छा विकल्प DbContext(string nameOrConnectionString);डेटाबेस निर्माण सामान के लिए एक रीड / राइट कनेक्शनस्ट्रिंग के साथ कंस्ट्रक्टर का उपयोग करना है और एक बाद कनेक्शन रीड स्ट्रिंग है।
जर्गेन स्टाइनब्लॉक

32

स्वीकार किए गए उत्तर के विपरीत, मेरा मानना ​​है कि विरासत पर रचना का पक्ष लेना बेहतर होगा । तब अपवाद को फेंकने के लिए SaveChanges जैसे तरीकों को रखने की कोई आवश्यकता नहीं होगी। इसके अलावा, आपको पहली बार इस तरह के तरीकों की आवश्यकता क्यों है? आपको एक वर्ग को इस तरह से डिजाइन करना चाहिए कि जब उसका उपभोक्ता उसके तरीकों की सूची को देखे तो वह मूर्ख न बने। सार्वजनिक इंटरफ़ेस को क्लास के वास्तविक इरादे और लक्ष्य के साथ संरेखित किया जाना चाहिए, जबकि स्वीकृत उत्तर में SaveChanges का अर्थ यह नहीं है कि प्रसंग केवल पढ़ा गया है।

उन जगहों पर जहां मुझे केवल-पढ़ने के लिए संदर्भ होना चाहिए जैसे कि CQRS पैटर्न के रीड साइड में , मैं निम्नलिखित कार्यान्वयन का उपयोग करता हूं। यह अपने उपभोक्ता को क्वेरी क्षमताओं के अलावा कुछ भी प्रदान नहीं करता है।

public class ReadOnlyDataContext
{
    private readonly DbContext _dbContext;

    public ReadOnlyDataContext(DbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public IQueryable<TEntity> Set<TEntity>() where TEntity : class
    {
        return _dbContext.Set<TEntity>().AsNoTracking();
    }
}

ReadOnlyDataContext का उपयोग करके, आप DbContext की केवल क्वेरी क्षमताओं तक पहुँच प्राप्त कर सकते हैं। मान लीजिए कि आपके पास ऑर्डर नाम की एक इकाई है, तो आप नीचे दिए गए तरीके से ReadOnlyDataContext उदाहरण का उपयोग करेंगे।

readOnlyDataContext.Set<Order>().Where(q=> q.Status==OrderStatus.Delivered).ToArray();

क्या यह विधि db_datareader के उपयोग के लिए केवल sql लॉगिन की अनुमति देती है? एक मानक DBContext EF के साथ जब मेरा क्वेरी कोड किसी भी SaveChanges () को शामिल नहीं करता है तब भी TABLE अनुमति अस्वीकृत कर देता है।
तक

2
और इसे विरासत से IDisposable
बनायें

सेट <> का उपयोग करने के बजाय, मैं सुझाव दूंगा <>। public IQueryable<TEntity> Get<TEntity>() where TEntity : class { return _dbContext.Query<TEntity>().AsNoTracking(); }
एलन नीलसन

@ शक्कर - यकीन नहीं है कि मैं ऐसा करूँगा। चूंकि इस कॉल ने DbContext नहीं बनाया था, इसलिए इसे इसका निपटान नहीं करना चाहिए। यह बाद में बग को ट्रैक करने के लिए कुछ कठिन हो सकता है।
एलन नीलसन

@AllanNielsen क्वेरी <> पदावनत है। इसके अनुसार सेट <> का उपयोग किया जाना चाहिए।
फ्रैंक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.