Entity Framework ile oluşturulmuş Entityler arasında null kontrolü yapmanın basit güzel bir yolu var mıdır?

Örneğin Entity Framework ile database first yöntemini kullanarak bir veritabanını örnekledik. Mesela Kullanici nesnesi, ona bağlı KullaniciAdres Nesnesi, ona bağlı Ilce ve ona bağlı Il tabloları var. Ben Kullanıcının İline erişmek istediğimde şöyle bir kod kullanıyorum:

var kullanici= db.Kullanici.Find(id);

var il=kullanici.KullaniciAdres.FirstOrDefault().Ilce.Il.IlAdi;

Böyle bir kod kullandığımda bütün alanlar dolu ise sorun yok. Ama Kullanıcının hiç adresi yoksa yada adresi varsa bile ona bağlı bir ilçe yoksa ve hatta (çok çok istisna olarak) o ilçeye bağlı bir il yoksa hata null exception fırlatacaktır. Onun içinde tek tek if kontrolü yapmak gerekiyor. Ortaya şöyle hem güzel olmayan hemde pek iyi olmayan kod parçaları çıkıyor:

var il=String.Empty;

if
(
kullanici!=null && 
kullanici.KullaniciAdres.Count()>0 && 
kullanici.KullaniciAdres.FirstOrDefault().Ilce!=null && 
kullanici.KullaniciAdres.FirstOrDefault().Ilce.Il !=null
)

{

   il=kullanici.KullaniciAdres.FirstOrDefault().Ilce.Il.IlAdi;

}

gibi bir kod çıkıyor. Hadi bunun için yaptık diyelim. Ama onlarca tablonun olduğu bir veritabanını modellediğimiz zaman mutlaka arada kaçanlar oluyor. Bundan başka null exceptionları engellemenin yolları var mı? Yada yaptığım sistem mi yanlış? veritabanı mantığı mı yanlış

soruldu: 17 Haz '14, 13:10

emrekacan's gravatar image

emrekacan
813304450
cevap kabul oranı: 9%

değiştirildi: 18 Haz '14, 00:01

AliR%C4%B1za%20Ad%C4%B1yah%C5%9Fi's gravatar image

AliRıza Adıyahşi ♦
7.9k146288


Eğer ilişkiler 0 ..1 to many ise evet bu şekilde kontrol etmelisiniz. Ama 1 to many ilişkisi varsa adresten sonrası garantidir. Adres null olabilir diyorsanız zaten bunu kontrol etmelisniz. Eğer 1 to many olarak tasarlarsanız kodlarınız aşağıdaki gibi değişir:

if(kullanici.KullaniciAdres.Any())
{
    // adres varsa ilçe de vardır, ilçe varsa il de vardır.
    var il = kullanici.KullaniciAdres.Ilce.Il.Ad;
}

Ama hepsi ayrı ayrı null olabilir diyorsanız, linq ile left join ile yine çekebilirsiniz (amaç liste çekmekse). Amaç kullanıcının ilini bulmak ise mesela,

iller.SelectMany(ilceler).SelectMany(adresler).FirstOrDefault(kullaniciId == kullaniciId)

Gibi direk çekersiniz, varsa gelir zaten, yoksa null olur -ki bu da string bir değer için hataya düşürmez. Bu arada söz dizim birebir değil.

Aslında gerçek bir senaryo üzerinden gidilirse daha verimli olur. Farklı gereksinimler için farklı çözümler olabilir, ama ilişkili veritabanı iyi tasarlanırsa çok fazla kontrol yapmazsınız. Zaten veritabanı ne kadar iyi tasarlanırsa, ORM nin avantajlarından o kadar çok yararlanılır.

permanent link

cevaplandı: 17 Haz '14, 15:30

AliR%C4%B1za%20Ad%C4%B1yah%C5%9Fi's gravatar image

AliRıza Adıyahşi ♦
7.9k146288
cevap kabul oranı: 44%

değiştirildi: 19 Haz '14, 04:50

Yani kısaca ya veritabanındaki null alanları azaltacağım yada tek tek kontrol edeceğim. Başka yolu yok :) Teşekkür ederim cevap için.

(19 Haz '14, 04:48) emrekacan emrekacan's gravatar image

tam olarak oyle sayılmaz aslında, yapacağınız seyi tam belirlemek demek istedigim. Yani ilin adını mı bulacaksınız, yoksa il ile beraber bir kullanıcı listesi mi cekecekseniz. Amaç ilin adını bulmaksa, null kontrolu yapmanıza gerek kalmayacak kod yazmalısınız. yani, hiyerarşiye, adresten ile gitmek yerine, ilden başlamak şeklinde yol izlersiniz.

(19 Haz '14, 04:56) AliRıza Adıyahşi ♦ AliR%C4%B1za%20Ad%C4%B1yah%C5%9Fi's gravatar image

Duruma göre değişebiliyor. Mesela Kullanıcı ayrıntı sayfası yaptığımızda Kullanıcının adreslerininde hepsini listeletmek istersek Kullanıcı tablosundan bir veri adres tablosundan birden fazla veri gelmesi gerekir. Adreslerde ilçeleri ilçelerde illeri çağırır. Çok dallanıyor yani. Dediğiniz gibi sadece il adı yazılacağı zaman yukardaki gibi basit kod parçası işe yarayabilir. Ben bu linq ile join işlemlerinide araştırayım. Tekrar teşekkürler.

(19 Haz '14, 08:24) emrekacan emrekacan's gravatar image

Konuyla direk alakalı degil ama, linq içerisinde sql string ler de çalıştırabilirsiniz.

(19 Haz '14, 08:39) AliRıza Adıyahşi ♦ AliR%C4%B1za%20Ad%C4%B1yah%C5%9Fi's gravatar image
Cevabınız
toggle preview

Bu soruyu takip et

E-Posta üzerinden:

Üyelik girişi yaptıktan sonra abonelik işlemlerini yapabilirsiniz

RSS üzerinden:

Cevaplar

Cevaplar ve Yorumlar

Yazı Formatlama

  • *italic* ya da _italic_
  • **bold** ya da __bold__
  • link:[text](http://url.com/ "başlık")
  • resim?![alt text](/path/img.jpg "başlık")
  • liste: 1. Foo 2. Bar
  • temel HTML etiketleri de kullanılabilir

Bu sorunun etiketleri:

×18
×4

Soruldu: 17 Haz '14, 13:10

Görüntüleme: 680 kez

Son güncelleme: 19 Haz '14, 08:39

powered by BitNami OSQA