entity framework - AsNoTracking() के लिए वैश्विक सेटिंग?




entity-framework change-tracking (4)

मूल रूप से मुझे विश्वास था कि

context.Configuration.AutoDetectChangesEnabled = false;

परिवर्तन ट्रैकिंग अक्षम कर देगा। लेकिन नहीं। वर्तमान में मुझे अपने सभी LINQ प्रश्नों (केवल पढ़ने के लिए परत) के लिए AsNoTracking() का उपयोग करने की आवश्यकता है। क्या डीबीकॉन्टेक्स्ट पर ट्रैकिंग अक्षम करने के लिए कोई वैश्विक सेटिंग है?


अद्यतन: यह वास्तव में काम नहीं किया था। टिप्पणी देखो!

जब मैं स्टैक ओवरफ्लो पर खोज करता हूं तो मुझे इससे नफरत है और जवाब है: "आप नहीं कर सकते!" या "आप कर सकते हैं, लेकिन केवल तभी जब आप अपने द्वारा किए गए हर कॉल को पूरी तरह बदल देते हैं।"

किसी को प्रतिबिंबित करें? मैं उम्मीद कर रहा था कि यह एक डीबीकॉन्टेक्स्ट सेटिंग होगी। लेकिन चूंकि यह नहीं है, मैंने प्रतिबिंब का उपयोग करके एक बनाया है।

यह आसान छोटी विधि डीबीसेट के सभी गुणों पर AsNoTracking सेट करेगी।

    private void GloballySetAsNoTracking()
    {
        var dbSetProperties = GetType().GetProperties();
        foreach (PropertyInfo pi in dbSetProperties)
        {
            var obj = pi.GetValue(this, null);
            if (obj.GetType().IsGenericType && obj.GetType().GetGenericTypeDefinition() == typeof(DbSet<>))
            {
                var mi = obj.GetType().GetMethod("AsNoTracking");
                mi.Invoke(obj, null);
            }
        }
    }

इसे एक अधिभारित डीबीकॉन्टेक्स्ट कन्स्ट्रक्टर में जोड़ें।

    public ActivationDbContext(bool proxyCreationEnabled, bool lazyLoadingEnabled = true, bool asNoTracking = true)
    {
        Configuration.ProxyCreationEnabled = proxyCreationEnabled;
        Configuration.LazyLoadingEnabled = lazyLoadingEnabled;
        if (asNoTracking)
            GloballySetAsNoTracking();
    }

यह प्रतिबिंब का उपयोग करता है, जिसका अर्थ है कि कोई जल्दी से टिप्पणी करेगा कि यह एक प्रदर्शन हिट है। लेकिन क्या वास्तव में यह बहुत हिट है? आपके उपयोग के मामले पर निर्भर करता है।


अपने व्युत्पन्न संदर्भ पर इस तरह की विधि को बस उजागर करने और प्रश्नों के लिए इसका उपयोग करने के बारे में क्या:

public IQueryable<T> GetQuery<T>() where T : class {
    return this.Set<T>().AsNoTracking();
}

विश्व स्तर पर AsNoTracking सेट करना संभव नहीं है। आपको प्रत्येक क्वेरी या प्रति ObjectSet ( DbSet नहीं) प्रति सेट करना होगा। बाद के दृष्टिकोण को ObjectContext एपीआई का उपयोग करने की आवश्यकता है।

var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
var set = objectContext.CreateObjectSet<T>();
set.MergeOption = MergeOption.NoTracking;
// And use set for queries

चूंकि इस प्रश्न को एक विशिष्ट ईएफ संस्करण के साथ टैग नहीं किया गया है, इसलिए मैं यह उल्लेख करना चाहता था कि ईएफ कोर में व्यवहार संदर्भ स्तर पर कॉन्फ़िगर किया जा सकता है

आप संदर्भ उदाहरण स्तर पर डिफ़ॉल्ट ट्रैकिंग व्यवहार भी बदल सकते हैं:

using (var context = new BloggingContext())
{
    context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

    var blogs = context.Blogs.ToList();
}

मेरे मामले में, क्योंकि मुझे पढ़ने / लिखने के बजाय पूरे संदर्भ की आवश्यकता है।

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

उदाहरण के लिए:

public virtual DbQuery<Campaign> Campaigns { get{ return Set<Campaign>().AsNoTracking();} }

टीटी टेम्पलेट में मैंने जिस तरह से किया है वह है:

public string DbQuery(EntitySet entitySet)
    {
        return string.Format(
            CultureInfo.InvariantCulture,
            "{0} virtual DbQuery<{1}> {2} {{ get{{ return Set<{1}>().AsNoTracking();}} }}",
            Accessibility.ForReadOnlyProperty(entitySet),
            _typeMapper.GetTypeName(entitySet.ElementType),
            _code.Escape(entitySet));
    }





change-tracking