Soru AsNoTracking () için global ayar?


Aslında buna inandım

context.Configuration.AutoDetectChangesEnabled = false;

değişiklik izlemeyi devre dışı bırakır. Ama hayır. Şu anda kullanmam gerek AsNoTracking() tüm LINQ sorgularımda (salt okunur tablom için). DbContext'te izlemeyi devre dışı bırakmak için global bir ayar var mı?


46
2017-10-04 12:04


Menşei




Cevaplar:


Bu soru belirli bir EF sürümü ile etiketlenmediğinden, şunu belirtmek istedim. EF Çekirdek davranış olabilir bağlam düzeyinde yapılandırılmış.

Varsayılan izleme davranışını bağlamda da değiştirebilirsiniz.   örnek seviye:

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

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

16
2017-10-01 17:15



bağlantın bana hata göster - Ali Yousefie
@AliYousefie teşekkür ederim, bunu düzelttim. - Amr Elgarhy


Türetilmiş içeriğinizde bunun gibi bir yöntemi açığa çıkarma ve sorgular için kullanmayla ilgili:

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

Ayar AsNoTracking küresel olarak mümkün değildir. Her sorguya veya her birine göre ayarlamanız gerekir ObjectSet (değil DbSet). İkinci yaklaşım, kullanım gerektirir ObjectContext API.

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

33
2017-10-04 12:29



Yalnızca GetQuery <T> gibi tek bir varlık gösterdiğinde Varlıklar arasında nasıl bir birleşimde bulunulur? Cevabınız için teşekkürler. - Vindberg
iki farklı sonuca katılabilirsiniz GetQuery aramalar - Ladislav Mrnka
Onun mümkün, ama sonra benim genel depo kurulumunu yeniden yapmak gerekiyor: / Ama öneri için teşekkürler. - Vindberg
@LadislavMrnka DbContext tarafından yakalanmayan bir sınıfın örneklerini döndüren sorgularım var. Bu durumda, bunu düşünmüyorum. <T> işe yarayacaktı. Öte yandan, belki de AsNoTracking gerekli değildir? - Candy Chiu


DbContext'inizde böyle bir şey yapabilirsiniz:

public void ObjectContext_OnObjectMaterialized(Object objSender, ObjectMaterializedEventArgs e)
{
    Entry(e.Entity).State = EntityState.Detached;
}

Bir nesne bağlamınız tarafından her gerçekleştiğinde, ayrılacak ve artık izlenmeyecektir.


2
2018-03-16 14:47



Bence bu işe yarıyor ama belki de bunu yapmanın en iyi yolu değil. AsNoTracking () bildiğim kadarıyla Nesneleri Takma ve Çıkarma. - Jone Polvora
Buradaki cevap, ikisi arasındaki fark üzerinde duruluyor. stackoverflow.com/a/20163424/219072 AsNoTracking () kesinlikle tercih edilen bir yaklaşım gibi geliyor. - emragins


Güncelleme: Bu gerçekten işe yaramadı. Yorumlara bakınız!

StackOverflow'ta arama yaptığımda nefret ediyorum ve cevap: "Yapamazsın!" veya "Yapabilirsin, ama sadece yaptığınız her bir çağrıyı tamamen değiştirirseniz."

Yansıma olan var mı? Bunun bir DbContext ayarı olacağını umuyordum. Ama öyle olmadığından, bir yansımayı kullanarak yaptım.

Bu kullanışlı küçük yöntem, DbSet'in tüm özelliklerinde AsNoTracking'i ayarlayacaktır.

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

Aşırı yüklü bir DbContext kurucusuna ekleyin.

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

Yansıma kullanır, yani birisinin bunun bir performans isabeti olduğunu hızlıca yorumlayacağı anlamına gelir. Ama bu gerçekten bir vuruş mu? Kullanım durumunuza göre değişir.


2
2017-11-25 21:05



Bunu test etmedim ama bildiğim kadarıyla AsNoTracking()sadece mevcut setin track-tracked olarak geri dönmesi IQueryable. Üzerine çağırıyor DbSet takip edilmeyen sorguları takip etmiyor. Bu koddan anladığım şey, aradığınız AsNoTracking() tüm takımlarınızda, ama hiçbir şey için iade edilen queryables kullanmıyorsanız bu bir şey yapmaz - Jcl
@Jcl, bunu kontrol etmeliyim. Benim için çalışıyor gibi görünüyor. - Rhyous
Şimdi test etmek için zamanım yok, ama ilk bakışta bana şüpheli görünüyor. Eğer bu işe yararsa, bu her zaman aradığınız anlamına gelir AsNoTracking() üzerinde DbSet bir bağlamda, sonraki tüm sorgular DbSet Aynı bağlamda takip edilmeyecek ... ve bazı garip davranışlar olurdu (özellikle de AsTracking() telafi etmek için). Eğer bu gerçekten işe yararsa, bunun bir hata ya da belgesiz bir özellik olduğunu söyleyebilirim :-) - Jcl
@Rhyous AsNoTracking () ayarının bir kez bu bağlantıya göre sonsuza dek ayarlanacağını düşünmüyorum. c-sharpcorner.com/UploadFile/ff2f08/...  Bunun neredeyse bir yıllık bir yorum olduğunu görüyorum .. lütfen Globally AsNoTracking'i ayarlamak için herhangi bir alternatifiniz varsa lütfen bize bildirin. - Raghav
Bulgularımı göndermeyi unuttuğum için beni affet. @Jcl belirtildiği gibi, sorgu başına. Yeni bir sorgu AsNoTracking () komutunu onurlandırmaz. EF (Depozit paterni) etrafında bir sarıcı uyguladım ve şimdi AsNoTracking'e ihtiyaç duyan aramalar var. - Rhyous


Benim durumumda Okuma / Yazma yerine okumak için bütün içeriğe ihtiyacım vardı.

Bu yüzden tt dosyasına bir değişiklik yaptım ve DbSet yerine DbQuery döndürmek için tüm DbContext özelliklerini değiştirdim, tüm özellikleri kümeleri kaldırıldı ve alır, ben Model.AsNoTracking () döndürdü

Örneğin:

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

Bunu tt şablonunda yaptım:

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


0
2018-01-05 00:43