Merhaba arkadaşlar,
Birlikte geçirdiğimiz bu 10 haftalık süreçte sizlere Entity Framework konusu hakkında bilgi vermeye çalıştım. Bu haftaki yazım Entity Framework hakkında paylaşacağım son yazım olacak. Bu süreç içerisinde Entity Framework konusunun yapı taşları olan CRUD işlemlerinden başlayarak, advance topic diyebileceğimiz Inheritance, Entity Framework Stored Procedure kullanımı gibi bir çok konuyu işledik. Bu haftaki yazımda ise bir önceki haftalarda yaptığımız uygulamalarda karşılaşılma olasılığı yüksek olan hataları bu hataların neden oluştuğunu ve çözümünü anlatmaya çalışacağım.
System.InvalidOperationException: The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
Yukarıdaki hata farklı bir içeriğe sahip entity objeleri kullandığımızda ve bu entity objeleri veritabanında bir ilişkiyi özelleştimeye ve veritabanını değişikliğe zorladığında karşımıza çıkar. Bu objeler işlem sırasında birbirlerinin hangi durumda olduklarını bilemezler ve birlikte işlem yapmayı reddederler. Birlikte işlem yapmayı reddettiklerinden ve ikiside aynı veritabanı parçası üzerinde çalışmak istemelerinden ötürü hata oluşur. Birden fazla ObjectContext kullanılan projelerde bu hatayla sıkça karşılaşırız.
Hatanın en güzel çözümü, birbirleriyle ilişkili entity objeler kullanmaktır. İlgili hatayla karşılaşmamak için size önereceğim yollardan biri foreign key kolonunu ve foreign keye ait idyi bütün entity objelerine bağlamayıp sadece ilişkili olan entity objesine atamak. Böylelikle birden fazla entity objesi aynı veritabanı bölgesinde çalışmayıp sadece ilgili entity objesi orada işlem yapacak ve aynı içeriğe sahip objeler oluşmayacaktır. Bu sizin için bir seçenek değilse, bir başka yolda önceden var olan entity objesi ile aynı içeriğe sahip bir entity objesi eklemek istediğimizde; bu iki objenin içeriğini yenileyip yeni bir objeye bağlayabiliriz yada var olan entity objesini yeni oluşturduğumuz entity objesine atayabiliriz. Fakat bu yollu uygularken dikkatli olmamız gerekir. Çünkü yeni oluşturduğumuz entity objemiz hala eski içeriğe sahip entity objesini refer ediyor ise aynı hatayı almaya devam ederiz.
System.ObjectDisposedException: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Bu hata ise ObjectContex objeleriyle ile Lazy Load entitylerini ilişkilendirmeye çalıştığımızda karşımıza çıkar. Aşağıda bu hata için yazılmış bir test var. Dilerseniz bu test metodunu inceleyelim.
Figür 1-Test Metodu |
Yukarıdaki test metodunda oluşturulan senaryoda geri product listesi döndüren bir fonksiyonumuz var. Bu oluşturduğumuz liste bir web uygulamasında bulunan listviewin databoundlarını oluşturacak. ProductModel.Name yukarıdaki satırlarda oluşturuluyor. Bu tanımlama birçok deadline(ulaşılamayan satır) oluşmasına neden olacaktır.
Bu hatayı çözmek için, eğer ObjectContexleri devam ettirmek istiyorsak C# garbage collectionın oluşturduğumuz entitylerin üstüsinden gelmesine izin vereceğiz. Bu işlemi yaptıktan sonra bu hata gerine nullpointer exception almamız beklenir.
Başlıca hataları yazdıktan sonra Entity Framework konusunda programımızın performansını artırmak için yapılması gereken bir kaç püf noktasından bahsetmek isterim.
ToList() methodunu Filtrelenmiş Iterationlardan Önce Kullanmayın.
Bir tablodan ilk 500 entityi getirmek istediğimiz zaman ilk önce ToList() metodunu çağırırsak öncelikle tüm tablodaki entityler gelecektir. Daha sonra ilk 500 entityi getirmek için yazdığımız satır çalışacaktır. Bu durumda ilk 500 entity dışındaki diğer tüm entityler boşu boşuna tablodan getirilmiş olacak ve bu durum bizi performans kaybına neden olacaktır. Kendi bilgisayarımızda bulunan local SQL veritabanında çalışırken bu performans kaybı pek gözlenmez fakat gerçek hayattaki uygulamalarda gözle görülür bir performans kaybı oluşur.
View State İçerisinde Entity Kullanırken Çok Dikkatli Olun.
Mümkün olduğunca View State içerisinde entity kullanmaktan kaçının. İlla kullanmak istiyorsanızda wrapper class oluşturun.
Çok Gerekli Olmadıkça ObjectContext Oluşturmayın.
Bu konu daha çok CPU performansıyla alakalı. ObjectContexler CPU performansını büyük oranda etkileyen yapılardır. Mümkün olduğunca az kullanmaya çalışın ya da daha önceden oluşturduğunuz ObjectContexleri tekrar kullanın. Döndüler içerisinde ObjectContex oluşturmayın.
Entity Framework performans artışı sağlamak için tavsiyelerde bulunduktan sonra Entity Framework blog yazımın sonuna gelmiş bulunuyorum. Umarım birlikte geçirdiğimiz bu 10 haftalık süreç yararlı olmuştur. Entity Framework ile alakalı herhangi bir konuda yardıma ihtiyaç duyarsanız veya herhangi bir sorunuz olursa lütfen yorum bırakın ya da mail yoluyla bana ulaşın. Bir başka blogda görüşmek üzere...