2012-02-17 18 views
5

I DAL bir besleme yöntemi vardır:Getiri veritabanı kayıtları LinqToSql kullanarak mı?

public IEnumerable<RecordType> GetRecords() 
{ 
    using (LinqDataContext context = new LinqDataContext()) 
    { 
     var records = context.RecordTable; 

     foreach (RecordType record in records) 
     { 
      yield return record; 
     } 
    } 
} 

tüketici yöntemi foreach döngü kayıtları kullanır. Bu şekilde, LinqToSql olay yerinin arkasında DataReader kullandığı için, RecordTable arasındaki tüm kayıtları önbelleğe almayan bir bellek kullanımını kaydetmek istiyorum.

  1. verim-dönen yukarıda kaynak tasarrufu ve daha hızlı bir diziye tüm kayıtları önbelleğe daha çalıştığını olduğu doğru mudur (.ToArray()):

    olsa bu senaryo üzerinde iki sorum var? Bir hata tüketen yöntemin foreach döngü içinde meydana gelecektir eğer alıcı yöntemi (ortada foreach döngü kıracak eğer

  2. veri bağlantısı otomatik olarak düzgün (I using deyimi demek) kapalı olacak gibi buldum VEYA gerekli kayıt ve break)?

cevap

3

, bu can bu şekilde çalışın (kesinlikle mümkündür) - ancak, bir Table<T> nolu çıplak sorgulama durumunda, ,, tüm arabellekleri ilk önce olabilir; Yineleme sırasında sayımı sorgulamayı veya bir izleme çalıştırmayı deneyebilirsiniz. Bu durumda ben şüpheli ilk önce arabelleğe alacaktır.

Re kapalı: Ayrıca bağlı olduğunu; p birisi foreach kullanıyorsa, o zaman evet: foreach beri açıkça finally aracılığıyla yineleyici yok eder. Ancak! Birisi yaparsa bu, garanti edilmez (çok yaramaz ve gevşek) örneğin:

sonra
var iter = yourData.GetEnumerator(); 
if(iter.MoveNext()) { 
    Console.WriteLine(iter.Current.Name); // first record of, say, 20 
} 
// and don't dispose the iterator == bad 

beri yineleyici yapar değil: kendisini tüketmek ve c: bunu düşmezse elden çıkarılan, b olsun düzgün şekilde kapanmayacaktır (numaralı 3 koşuldan herhangi biri'u düzgün şekilde kapatır). Vurgu: Bu bir patolojik durumdur: normal olarak “kapanacak, evet” demek mantıklıdır. Eğer garantili olmayan arabelleğe istiyorsanız

, sen bufferedfalse ayarlı ise, o vardır "şık" olduğuna dikkat:

IEnumerable<Customer> customers = connection.Query<Customer>(
     "select * from Customer", buffered: false); 

(aynı zamanda parametreleri vb işleyebilir)

3

1) yield mutlaka tüm değerleri almak için hızlı olmayacak, ancak veritabanı tüm sonuç vermedi önce kod sonuçlarını ele başlama olanağı sağlayacak. Yani, sonuç, ortaya çıktığı andaki ilk sonucu döndürürken, ToArray() öğesinin geri dönmeden önce tüm sonuçların gösterilmesini beklemesi gerekir. Tabii ki, temel sağlayıcılar, arabelleğe alma veya başka nedenlerle tüm sonuçları bir defada iade ederse, bu durum bir fark yaratmayabilir.

2) Evet, using kullanmakta blok çıkmak nasıl olursa olsun LinqDataContext imha edecek (istisnalar/iade/mola/...) temel bir sorgu yürütme durumunda

+1

Aslında 2 - bu en olarak ' –

+0

@MarcGravell Olmadığını (doğru) söz ediyoruz sanıyorum using' olan "garantili" olarak kesinlikle değil Numaralandırma tamamlandı mı, yoksa başka bir şeyi mi özlüyorum? –

+0

evet elle yineleyici yürüyüş ve yanlış yapıyor. En aklı başında insanların kullanacağı 'foreach' kullanırken sorun değil. –

2
  1. yineleyici tembel olarak değerlendirilecektir. İlk maddeyi çekecek ve ardından tüketicisine "ver".Performans etkisi, LinqDataContext'in nasıl uygulandığına bağlı olacaktır (öğeleri dahili olarak önbelleğe alabilir). ToArray() veya ToList() kullanılarak, devam etmeden önce LinqDataContext üzerinden tüm elemanları zorlar. Bu nedenle, ToArray() kullanarak LinqDataContext her öğeyi döndürene kadar hiçbir şey vermezsiniz. Optimal olsun ya da olmasın, size kalmış.
  2. Evet, doğru şekilde tatbik edilecektir "kullanarak". "Arayan düzgün davranır sürece"