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

Entity Framework’te Unable To Create A Constant Value Of Type ‘xxx’. Only Primitive Types Or Enumeration Types Are Supported In This Context Hatası ve Çözümü

Merhaba,

Geçenlerde üzerine çalıştığım bir projede almış olduğum bir hata üzerine konuşuyor olacağız. Bu hatanın diğerlerinden farkı belli başlı, tespit edilebilir durumlarda karşılaşabilmemizden ziyade; birden fazla sergilenen yaklaşımda karşılaşılabilen ve geniş yelpazeli bir olası hata olmasıdır.

İnceleyeceğimiz hata makalemizin başlığında olduğu gibi

Entity Framework’te Unable To Create A Constant Value Of Type ‘xxx’. Only Primitive Types Or Enumeration Types Are Supported In This Context

hatasıdır.

Bu hata; Entity Framework, LINQ vs. gibi Framework yapılarında genellikle tanımlanmayan veri türleri üzerinde alınan bir hatadır. Zaten hatada da bahsedilen yapılan çalışma(artık ne ise)da üzerinde çalışılan veri türünün bilinen türlerden yahut numaralandırıcılardan olması gerekiyor.

Şimdi bizler bir kaç örnek durumu ele alarak ilgili hata durumunu gözlemleyecek ve ardından çözümler üzerine istişare ederek bir sonuca varacağız.

Öncelikle vereceğimiz örneklendirmelerde Entity Framework üzerinden çalışmalarımızı icra edeceğimizi şimdiden bildiririm.

İlk başta aşağıdaki örneği inceleyelim.

            NorthwindEntities vt = new NorthwindEntities();
            Personeller p = new Personeller { Adi = "Nancy", SoyAdi = "Davaleo" };
            vt.Set<Personeller>().Contains(p);

Dikkat ederseniz “Set<Personeller>()” metodundan dönen sonuç üzerinden “Contains” metodu ile veri eşleştirme sonucu sorgulanmaktadır. Bu komutları derleyip çalıştırdığımız zaman aşağıdaki sonuçla karşılaşmaktayız.
Entity Framework'te Unable To Create A Constant Value Of Type 'xxx'. Only Primitive Types Or Enumeration Types Are Supported In This Context Hatası ve Çözümü

Görüldüğü üzere “Set<Personeller>()” metodunun tipi “System.Data.Entity.DbSet<Personeller>”dir. Buradaki çalışmada “Set<Personeller>()” metodu neticesinde dönen sonucu “.ToList()” metodu ile List koleksiyonuna çevirdiğimiz zaman sorunumuz çözülecektir.

            NorthwindEntities vt = new NorthwindEntities();
            Personeller p = new Personeller { Adi = "Nancy", SoyAdi = "Davaleo" };
            vt.Set<Personeller>().ToList().Contains(p);

Dikkatinizi “System.Data.Entity.DbSet<T>” tipine çekmek istiyorum. 😉

Bir başka örneği incelersek eğer,

            NorthwindEntities vt = new NorthwindEntities();
            var Personeller = (from personel in vt.Personeller
                               select personel
                               ).ToList();

            var Satislar = (from satislar in vt.Satislar
                            where 
                            (Personeller.Any
                            (p => p.PersonelID == satislar.PersonelID))
                            select satislar).ToList();

Buradaki duruma göz atarsak eğer;
Entity Framework'te Unable To Create A Constant Value Of Type 'xxx'. Only Primitive Types Or Enumeration Types Are Supported In This Context Hatası ve Çözümü
“List<Personeller>” ile “DbSet<Satislar>” koleksiyonları içerisinden alınan veriler üzerinde bir karşılaştırılma yapılmaktadır. Bu kodu derleyip çalıştırdığımızda da aşağıdaki aslen konumuzla alakalı durumla karşılaşılacaktır.
Entity Framework'te Unable To Create A Constant Value Of Type 'xxx'. Only Primitive Types Or Enumeration Types Are Supported In This Context Hatası ve Çözümü
Haliyle tekrardan şaibe yaratan “DbSet<T>” metodu kullanılmaktadır. Yapmamız gereken karşılaştırmada rol alan iki tipten birini diğerine benzetmektir.

1. Yol 2. Yol
Entity Framework'te Unable To Create A Constant Value Of Type 'xxx'. Only Primitive Types Or Enumeration Types Are Supported In This Context Hatası ve Çözümü Entity Framework'te Unable To Create A Constant Value Of Type 'xxx'. Only Primitive Types Or Enumeration Types Are Supported In This Context Hatası ve Çözümü
Görüldüğü üzere Satislar tablosunu .ToList metodu ile List tipine çevirebiliriz. Ya da Personeller sorgusundaki .ToList metodunu silerek sorgu sonucunu koleksiyon olarak elde etmekten vaz geçeriz. Haliyle görüldüğü üzere IQueryable<T> tipinden sonucu elde ederiz.

Aşağıda da görüldüğü üzere IQueryable<T> tipi aslen DbSet<T> referansının Base Class’ıdır. O yüzden amacımız olan benzerleştirme işlemimiz başarılı olmuştur diyebiliriz.

Entity Framework'te Unable To Create A Constant Value Of Type 'xxx'. Only Primitive Types Or Enumeration Types Are Supported In This Context Hatası ve Çözümü

Bu örneğimizde, DbSet<T> tipiyle yapılan çalışmalarda dikkatli olmanız gerektiğini tekrardan göstermiş olmaktadır. 😉

Ve son olarak aşağıdaki durumu inceleyelim.

            NorthwindEntities vt = new NorthwindEntities();
            var Personel = vt.Personeller.Where(p => p.PersonelID == 3).DefaultIfEmpty(new Personeller { Adi = "Gençay", SoyAdi = "Yıldız" }).First();

Bu koduda derleyip çalıştırdığımız zaman beklenilen durumla karşılaşmaktayız.
Entity Framework'te Unable To Create A Constant Value Of Type 'xxx'. Only Primitive Types Or Enumeration Types Are Supported In This Context Hatası ve Çözümü
Dikkat edilirse eğer Personeller DbSet<T> iken DefaultIfEmpty metodu generic yapısından dolayı DbSet<T>’nin base classı IQueryable<T> olarak gelmektedir. Haliyle bu iki metod sonuç olarak aynıdır. Ama sonuncu metodumuz First ise geriye sadece Personeller tipi döneceğinden dolayı bu hata kaçınılmaz olmaktadır.

Yapmamız gereken ortadaki tip farkını kaldırmaktır.
Entity Framework'te Unable To Create A Constant Value Of Type 'xxx'. Only Primitive Types Or Enumeration Types Are Supported In This Context Hatası ve Çözümü
Görüldüğü üzere .ToList metodu sayesinde bu işlemi başarıyla gerçekleştirebilmekteyiz.

Burada da DbSet<T> tipiyle yapılan çalışmalarda dikkatli ve tetikte olmanızı bir kez daha vurgulamış olalım. 😉 🙂

Evet…
Bir uzun ve zahmetli yazının daha sonuna gelmiş bulunmaktayız.
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

3 Cevaplar

  1. Mustafa dedi ki:

    peki 1 milyon satır tabloya where ile anonymus type ile sorgu attığımızda tolist dersek bütün tabloyu ram e çekip sorgular bu durumda ne yapılabilir ?

    • Gençay dedi ki:

      IQueryable tipinde Where şartının yazımına devam edebilir ardından sorguyu ya gecikmeli çalışmayla yahut .ToList gibi tetikleyici bir metotla execute edip, bellekte direkt hedef verilerin olmasını sağlayabilirsiniz.

  2. Murat dedi ki:

    Elinize sağlık hocam

Bir cevap yazın

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