EntityFramework Stored Procedure Çalıştırma

EntityFramework için bizi Ado.Net’in standart mekanizması olan SqlCommand’lar, SqlConnection’lar deryasından kurtaran en büyük nimet demek yanlış olmaz. Faydaları saymakla bitmez, karmaşık sogulardan, sürekli bağlantı açıp kapatmaktan ve gibi gibi bir ton angaryadan. Geri dönüş tiplerini belli şartlar altında ayarlayabilmek, gereksiz sorgulardan veritabanımızı soyutlayabilmek, Insert, Update, Delete gibi işlemlerimizi çok daha Object Oriented hale getirmek gibi bir sürü konu sayabiliriz.

Elbette kimine göre ufak tefek kimine göre biraz daha büyük çaplı sayılabilecek bazı performans sıkıntılarıyla karşımıza çıksa da yine de bir çok şeye değer diyebiliriz.

Bildiğiniz gibi yıllarca SQL tarafında ilişkili ve bir o kadar karmaşık sorguların tümünü INNER JOIN diye kodladığımız cümleciklerle tamamladık ve tablolar arası ilişkiyi kurarak sonucu aldık. Peki gel gelelim Entity Framework ile bu sorguları (JOIN) işlemlerimizi en performanslı şekilde nasıl yapabiliriz? Veya mümkün müdür?

Elbette mümkün. Cevabını verebilmek bu yazıdan geçiyor. Gelin hep beraber nasıl yapabileceğimizi inceleyelim ve uygulamada göz atalım.

TutoriolEntity diye bir entity oluşturduğumuzu düşünelim ve aşağıdaki şekilde objemizi create edelim.

TutoriolEntity tutorialEntity = new TutoriolEntity();

Şimdi ikinci adımda MSSQL tarafında SP_GetAllUserForCountry adında bir prosedürümüz olduğunu varsayıyoruz. İçerisinde standart bir inner join kullanmış olalım;

CREATE PROC SP_GetAllUserForCountry
AS
SELECT U.ID, U.Name, U.Surname, U.Phone, C.Name AS CountryName FROM Users U INNER JOIN Country C ON U.CountryID = C.ID

Gördüğünüz gibi burada Users adındaki tablomu Country isimli tablomla CountryID ve ID’yi eşleştirecek şekilde birbirine bağladım. Şimdi buradaki en ama en önemli ayrıntı şu ki, geriye çağırdığımız “U.Name, U.Surname, U.Phone, C.Name” alanlarının Model tarafımızda da bir class içerisinde karşılığı olmalı nasıl mı? Şimdi Models dizinimize sağ tıklayarak aşağıdaki gibi bir class (sınıf) oluşturuyoruz.

public class UserCountryView
{
public int ID { set; get; }
public string Name { set; get; }
public string Surname { set; get; }
public string Phone { set; get; }
public string CountryName { set; get; }
}

Burada püf noktamış şu; Name sütunu her iki tabloda da var. Users tablosunda da Country tablosunda da Name adında bir sütunumuz var. Bu yüzden yukarıdaki şekilde prosedürümüzde “C.Name AS CountryName” kullandık ki bu sütunun ismi bize CountryName olarka dönsün. Devamında ViewClass’ımızı tanımlarken de yeniden adlandırdığımız hücreyi “CountryName” kullanmış olduk. Böylece .net gelen Name’in ne için geldiğini anlayacak ve ilgili değişkene atayacaktır.

Anlaşılmış olacağı üzere burada çağırdığımız ve kod kısmında görmek istediğimiz tüm alanları class’ımızın içerisinde aynı isimle tanımlıyoruz ki prosedür den yanıt döndüğünde neyi nereye atacağını görsün ve bilsin.

Ve son olarak aşağıdaki şekilde modelimize atayacak şekilde prosedürümüzü tetikliyoruz.

List<SqlParameter> sqlparameters = new List<SqlParameter>();
tutorialEntity.Database.SqlQuery<UserCountryView>("SP_GetAllUserForCountry", sqlparameters.ToArray());

Şimdi sizin aklınızda iki soru var. 🙂 Bir sqlparameter nedir? İki neden böyle atanır? (Tabi bu işin şaka kısmı)

Burada SqlQuery fonksiyonumuz bizden mutlaka ama mutlaka bir sqlparameters LİSTESİ istiyor. Bizim mevcut prosedürümüzde bir parametremiz olmadığı için biz boş bir liste oluşturup ToArray() dedikten sonra prosedürümüze gönderiyoruz. Konu sadece bundan ibaret. Tabi bu arada prosedürümüzün ismini verdiğimiz yere de dikkat edelim. Çünkü eğer işi kod tamamlamaya bırakırsak bize ProcedureName diye değil “SQL” diye soruyor. Yanlışlıkla prosedürümüzün tamamını buraya yazmayalım 😀

Bir de tabi bu dönüşü bir değişkene atarsak tadından yenmez 🙂

var allUsersAndCountry = tutorialEntity.Database.SqlQuery<UserCountryView>("SP_GetAllUserForCountry", sqlparameters.ToArray());

gibi.

Peki son olarak parametre göndermek isteseydik ne yapacaktık? İşte o zaman sorgumuz aşağıdaki şekle geliyor;

CREATE PROC SP_GetAllUserForCountry
(
@UserName NVARCHAR(50),
@CountryID INT
)
AS
SELECT U.ID, U.Name, U.Surname, U.Phone, C.Name AS CountryName FROM Users U INNER JOIN Country C ON U.CountryID = C.ID WHERE U.UserName = @UserName AND C.ID = @CountryID

çağırma kısmı da;

TutoriolEntity tutorialEntity = new TutoriolEntity();
List<SqlParameter> sqlparameters = new List<SqlParameter>();
sqlparameters.Add(new SqlParameter("UserName", username));
sqlparameters.Add(new SqlParameter("CountryID", password));
var allUsersAndCountry = tutorialEntity.Database.SqlQuery<UserCountryView>("SP_GetAllUserForCountry @UserName, @CountryID", sqlparameters.ToArray());

Burada da son hatırlatma, SqlParameter listemizin içerisine değişkenleri hangi sıra ile ekliyor isek prosedürü çağırdığımız string nesnesinde de değişkenleri aynı sırada vermeliyiz. Yani;

(KESİNLİKLE YANLIŞ!!!)
List<SqlParameter> sqlparameters = new List<SqlParameter>();
sqlparameters.Add(new SqlParameter("UserName", username));
sqlparameters.Add(new SqlParameter("CountryID", password));
var allUsersAndCountry = tutorialEntity.Database.SqlQuery<UserCountryView>("SP_GetAllUserForCountry @CountryID, @UserName", sqlparameters.ToArray());

(KESİNLİKLE DOĞRU)
List<SqlParameter> sqlparameters = new List<SqlParameter>();
sqlparameters.Add(new SqlParameter("UserName", username));
sqlparameters.Add(new SqlParameter("CountryID", password));
var allUsersAndCountry = tutorialEntity.Database.SqlQuery<UserCountryView>("SP_GetAllUserForCountry @UserName, @CountryID", sqlparameters.ToArray());

Bir sonraki yazı da görüşmek üzere. Sorusu olan arkadaşlar var ise lütfen yorum kısmına yazmaktan çekinmesinler. Herkese az hatalı günler dilerim 🙂

Share this Story

Related Posts

2
Kimler Neler Demiş?

avatar
1 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
edomurcukÖzkan AKSOY Recent comment authors
  Subscribe  
En Yeniler Eskiler Beğenilenler
Bildir
Özkan AKSOY
Ziyaretçi
Özkan AKSOY

Dışarıdan parametreyi nasıl aldırabiliriz? ben denedim ama yapamadım? public ActionResult UrunDetay(string Kod) { //IEnumerable DetayGetir = db.Database.SqlQuery // (“exec SpModelEnvanterParam Modelkodu”,Kod).ToList(); //return View(DetayGetir); List sqlparameters = new List(); sqlparameters.Add(new SqlParameter(“Modelkodu”, Kod)); var UrunDetay = db.Database.SqlQuery(“SpModelEnvanterParam @Modelkodu,kod”, sqlparameters.ToArray().ToList()); return View(UrunDetay); }

Search