2015-01-14 19 views
10

ArkaplanGarip davranışları endswith yöntem

Ben yalnızca bir sütun içeren bir tablo var: Adı. Orada sadece dört satır, içinde I

var email = "[email protected]"; 
Table.Where(x => email.EndsWith(x.Name)); 

sorgulamak durumunda

| Name  | 
| test1.com | 
| test2.com | 
| test3.com | 
| test4.com | 

Sorun

demek boş bir liste elde edersiniz. ama önce tüm satırları sorgulamak ve bu

var email = "[email protected]"; 
Table.ToList().Where(x => email.EndsWith(x.Name)); 

gibi bellekte nerede hesaplamak ben alırsınız bir liste doğrudur sadece test2.com hangi içerir.

ilk sorgu için oluşturulan SQL ı yerine denedim

SELECT "Extent1"."Name" AS "Name" 
FROM "USER"."Table" "Extent1" 
WHERE ((NVL(INSTR(REVERSE(:p__linq__0), REVERSE("Extent1"."Name")), 0)) = 1) 

geçerli: p__linq__0 '[email protected]' ve SQLDeveloper sorguyu çalıştıran, sonuç doğrudur.

Ben endswith değiştirirseniz

() için İçeriyor Fazla Bilgi(), sorun gitmiş olacak. İçeren için Buraya oluşturulan SQL olduğu()

SELECT "Extent1"."Name" AS "Name" 
FROM "USER"."Table" "Extent1" 
WHERE ((NVL(INSTR(:p__linq__0, "Extent1"."Name"), 0)) > 0) 

Eğer endswith nesi veya yöntemi TERS bir fikrin var mı?

Çevre

  • EF5.0
  • .NET4.5
  • Oracle11g
  • Bu cümle beni ilgilendiren ve 3
+3

ayarlandığını (iki senaryo için) hatırlayın. Onun neden yaptığı SQL'i oluşturduğunu açıklayamıyorum ... ama ürettiğim her IQueryable ile kontrol etmek yaygın bir uygulamadır. – Derek

cevap

3

bırakın ODP.NET11.2 EF kullanan kişilerle yaygın tuzak:

bu aslında C# EndsWith gerçekleştirmek ardından belleğe tüm tabloyu gerçekleşmesi ve çünkü
Table.ToList().Where(x => email.EndsWith(x.Name)); 

bölüm Table.ToList() kötü parçasıdır. Bu hat: Tablo makul boyutu büyüdükçe zaman korkunç şekilde yavaş olacak gibi ben sadece genel prensibi üzerine bu yaklaşımı ikaz ediyorum

Table.Where(x => email.EndsWith(x.Name)); 

.Bir sütun depolama e-postaların alan adları üzerinde eşlenmesi gerekiyorsa, ayrıca

var email = "[email protected]"; 

/* You should null check this of course and not just assume a match was found */ 
var domain = Regex.Match(email , "@(.*)").Groups[1].Value; 

/* Note: ToList() materialisation happens at the end */ 
var result = Table.Where(x => x.Name == domain).ToList(); 

: sorgu sorgu oluşturmak olarak e-posta etki alanını dışarı bölerek veritabanını vurur önce ağır işi yapabilir Daha sonra tercih ettiğim yaklaşım, e-postayı bölmek ve etki alanı adını dizine eklediğiniz ve yalnızca eşleştirdiğiniz ayrı bir sütunda depolamak olacaktır. Bu, ölçeklenecek ve yönetilmesi çok daha kolay olacaktır. Bu günlerin verilerinin ucuz olduğunu unutmayın ... özellikle endekslenemeyen tablo taramaları ile karşılaştırıldığında.

Ayrıca veritabanı Bu her zaman SQL ile doğrudan IQueryables kullanırken SQL EntityFramework üretir kontrol etmelidir neden olarak harika bir örnek CI için (harf büyüklüğüne duyarlı)

+0

Peki, cevap EndsWith EF'de desteklenmiyor mu? Bunu açıklayan herhangi bir belge göremedim. Bir bağlantın var mı? – Moozz

+0

Hayır, cevap yukarıda söylediğim şey ... buna ihtiyacınız yok. Sadece alan adını C# ile ayıklayın ve sorguya iletin. C# ve sql arasındaki sınırları anlamadığınızı düşündüğümden cevabımı tekrar okuduğunuzdan emin olun. Bir EF tablosu öğesinde ToList() öğesini çağırdığınızda, performans için korkunç olan ve ölçeklenmeyen tüm tabloyu yansıtıyorsunuz (belleğe çekiliyor). Bu işleri açıklığa kavuşturuyor mu? Kafa karıştırıcı başka bir şey var mı? –

+0

ToList() öğesinin tüm satırları belleğe çekeceğini anlıyorum. EndsWith'in neden işe yaramadığını merak ediyorum. Oluşturulan SQL Tamam görünüyor ama çalışmıyor. Neyse, haklısın, EndsWith'i kullanmak zorunda değilim. – Moozz

İlgili konular