Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

‘LINQ to Entities Does Not Recognize The Method ‘Int32 ToInt32(System.Object)’ Method, And This Method Cannot Be Translated Unto A Store Expression.’ Hatası ve Çözümü

Merhaba,

Projelerimizde kullandığımız ve bizlere Entity Data Modeller üzerinde hızlı bir şekilde sorgulama imkanı sağlayan LINQ sorguları üzerinde başlıkta da gördüğünüz gibi aşağıdaki olası hatayı alabilirsiniz.

System.NotSupportedException: ‘LINQ to Entities does not recognize the method ‘Int32 ToInt32(System.Object)’ method, and this method cannot be translated into a store expression.’

Hatamızın görsel hali ise aşağıdaki gibidir;
'LINQ to Entities Does Not Recognize The Method 'Int32 ToInt32(System.Object)' Method, And This Method Cannot Be Translated Unto A Store Expression.' Hatası ve Çözümü
Evet… Karşılaşılması muhtemel hatamız budur. Peki bu hatayı neden almaktayız?
Öncelikle şunu belirtmeliyim ki, LINQ teknolojisini kullanırken sorgu mantığını göz önüne almazsak bu hatayla karşılaşmamız oldukça yüksek ihtimaldir. Nihayetinde ben bir çalışma esnasında bu mantığı göz ardı ettiğim için bu hataya haddinden fazla mağruz kalıp uygulama tasarımını farklı bir şekilde inşa etmek durumunda kalmış bulunmaktayım.

Peki ne hoca bu mantık?” diye sabırsızca sorduğunuzu duyar gibiyim. Hadi gelin açıklayalım.

LINQ sorgularında yazmış olduğumuz kalıp veritabanında çalıştırılacak sorguyu hazırlamaktadırlar. Eee haliyle ilgili kalıbı yazmak demek; sorguyu oluşturup, veritabanında çalıştırıp ardından sonucu getirir manasına gelmemektedir.

Şimdi aşağıdaki kod bloğunu ele alalım.

            Northwind2Entities db = new Northwind2Entities();

            var Personeller = from Personel in db.Personeller
                              select Personel;

Bu kod bloğundaki kalıp, ilgili sorguyu veritabanına gönderip gelen veri kümesini var tipinden Personeller referansına atamamaktadır ! ! ! Çünkü bu kalıp sadece sorguyu hazırlamaktadır. Yapılan LINQ sorgusunun veritabanında execute edilmesi için herhangi bir yapı tarafından çağırılması gerekmektedir. Örneğin bu yapı foreach döngüsü olabilir;

Çağrılmadan Önce Çağrıldıktan Sonra
'LINQ to Entities Does Not Recognize The Method 'Int32 ToInt32(System.Object)' Method, And This Method Cannot Be Translated Unto A Store Expression.' Hatası ve Çözümü 'LINQ to Entities Does Not Recognize The Method 'Int32 ToInt32(System.Object)' Method, And This Method Cannot Be Translated Unto A Store Expression.' Hatası ve Çözümü

Dikkat ederseniz LINQ sorgumuz foreach tarafından çağrıldığı zaman sorgu haline getirilip veritabanında execute edilmiştir.

foreach döngüsünden ziyade LINQ sorgusu neticesinde .ToList() metodu çağrılırsa eğer tekrardan ilgili ifade veritabanında execute edilecektir.

Bizler LINQ sorgularının iterasyonel ya da fonksiyonel çağrım sonucu çalıştırılmalarına Ertelenmiş Çalışma(Deferred Execution) demekteyiz.

İşte… LINQ sorgularını oluştururken göz önüne almamız gereken yapısal mantık bu Deferred Execution olayıdır.

Konumuz olan “LINQ to Entities does not recognize the method ‘Int32 ToInt32(System.Object)’ method, and this method cannot be translated into a store expression.” hatası ise bu bahsettiğim LINQ sorgu mekanizmasına rağmen aşağıdaki gibi bir kullanım sergilemekten kaynaklanmaktadır.'LINQ to Entities Does Not Recognize The Method 'Int32 ToInt32(System.Object)' Method, And This Method Cannot Be Translated Unto A Store Expression.' Hatası ve Çözümü

Görüldüğü üzere .ToList() metodu çağrılana kadar ilgili LINQ sorgusu bünyesinde bir Convert işlemi yapılmaya çalışılmıştır. Eee haliyle compiler elde bir sorgu olmadığı için Convert.ToInt32 metodunun T-SQL karşılığını bulamayacağından dolayı bu hatayı vermektedir. Bu hata aşağıdaki gibi bir manevrayla rahatlıkla aşılabilmektedir.

        public ActionResult Index(int? id)
        {
            Northwind2Entities db = new Northwind2Entities();

            if (id != null)
            {
                int ID = Convert.ToInt32(id);
                var GelenPersonel = (from Personel in db.Personeller
                                    where Personel.PersonelID == ID
                                     select Personel).ToList();
            }
            return View();
        }

Yani LINQ sorgusunun içerisinde bir Convert işlemi yapmaktansa bu işlemi sorgu dışında gerçekleştirip, ardından elde edilen değeri direkt olarak sorguya eklememiz bu hatadan kurtulmanızı sağlayacaktır.

Benzer şekilde aşağıdaki Extension metot yapıları ile sorgulama içinde geçerli olacaktır.
'LINQ to Entities Does Not Recognize The Method 'Int32 ToInt32(System.Object)' Method, And This Method Cannot Be Translated Unto A Store Expression.' Hatası ve Çözümü
Yapmamız gereken bir önceki örnekte verilen çözümü uygulamak, yani sorgu içerisindeki Convert işlemini dışarıda halletmek yeterli olacaktır.

        public ActionResult Index(int? id)
        {
            Northwind2Entities db = new Northwind2Entities();
            int ID = Convert.ToInt32(id);
            if (id != null)
                db.Personeller.FirstOrDefault(y => y.PersonelID == ID);
            return View();
        }

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

8 Cevaplar

  1. Dinçer Aydın dedi ki:

    çok teşekkür ederim linq to sql ile çalışırken saatlerdir bu hataya takılıp kalmıştım ama şuan çözüldü sorunum çok sağolun.

  2. malik masis dedi ki:

    Ben de geçenlerde bu hatayla karşılaştım ama daha iyi araştırınca daha güzel yolunu buldum. İşinize yarar diye paylaşmak istedim.
    https://stackoverflow.com/questions/9970100/calling-a-method-inside-a-linq-query
    AsEnumerable() kullanırsanız bu trcikleri kullanmaya gerek kalmaz.

  3. Mesut dedi ki:

    EyvAllah üstad sayende bir bilgi daha öğrendik ve sorunumuzu çözdük

  4. albus dedi ki:

    ben de 3 saat uuğraştım kod yanllış sanıyorum ya allahtan gördüm burayı

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir