2010-03-12 14 views
12

arama fonksiyonunda .. NTEXT alanlardaLinq: Bir harf duyarlı veritabanı ile SQL Server 2005 kullanıyorum

tolower() kullanarak, ben varlıkları için bir Linq oluşturmanız (L2E) sorgu bu kurallara veritabanındaki verilerle birkaç dizeleri karşılaştırmak bir "nerede" maddesi ile:

  1. karşılaştırma bir olan mod, sıkı değil karşılaştırmak "içerir": kolay dize en İçeriyor olarak() metodu izin verilir L2E
  2. Karşılaştırma, büyük/küçük harf duyarlı olmalıdır: Her iki öğede de Toes() öğesini duyarsız bir karşılaştırma yapmak için kullanıyorum.

Tüm bu Gerçekten iyi bir performans ama şu İstisna koştu: benim alanlardan birinde "değişken veri türü nmetin alt fonksiyonunun argümanı 1 için geçersiz".

Bu alanın bir NText alanı olduğu ve bunun üzerinde bir ToLower() gerçekleştiremediğim görülüyor.
Bu NText alanında bir büyük/küçük harfe duyarsız Contains() gerçekleştirebilmek için ne yapabilirim? Büyük/küçük harfe duyarlı olmayan bir karşılaştırma yapmak için hiçbir zaman .ToLower()'u kullanmayın.

cevap

26

İşte nedeni:

  1. Muhtemelen yanlış (istemci harmanlama, türkçe ve DB harmanlama programınız olmayabilir) olabilir. Bu, yüksek verimsizdir; Yayılan SQL, büyük harf duyarlı olmayan bir harmanlama ile = yerine LOWER olur.

Bunun yerine, StringComparison.OrdinalIgnoreCase veya StringComparison.CurrentCultureIgnoreCase kullanın: Equals, StartsWith vb aksine, bir StringComparison argüman için bir aşırı yoktur: Bir problem var

var q = from f in Context.Foos 
     where f.Bar.Equals("hi", StringComparison.OrdinalIgnoreCase) 
     select f; 

Ama Contains() için

. Niye ya? İyi soru; Microsoft'a sorun.

Bu, SQL Server'ın LOWER'daki sınırlamasıyla birlikte, istediğinizi yapmak için basit bir yol olmadığı anlamına gelir.

Olası geçici çözümler şunları içerebilir:

  • bir tam metin dizini kullanın ve bir prosedürde bir arama yapın.
  • kullanın Equals veya StartsWith yerine, mümkünse görev
  • Değişim sütunun varsayılan harmanlama için?
+0

hum ... Seni tolower() kullanarak yanlış olduğunu söyle tahmin ama ben başka bir çözüm var: - harmanlama değiştirme sadece bazı arama kriterlerine için çok fazla iş ve risk - & startswith kazandı Eşittir Buraya ihtiyacım var. NText alanını NVarchar'a dönüştürmeyi ve kullanıcı girdisini sınırlamayı düşünüyorum ... Durumumda performans gerçekten önemli değil. –

+0

Sadece seçeneklerin neler olduğunu anlatarak çalışıyorum, sizin için bazı ideal seçeneklerin var olduğunu iddia etmiyorum .... –

5

Burada bir lambda ifadesi kullanın ve alt maddeyi işleyebilecek bir ara liste oluşturun.

var q = Context.Foos.ToList().Where(s => s.Bar.ToLower().Contains("hi")); 

Çok verimli değil, ama işe yarıyor.Eğer nereye maddede ek yüklemleri varsa o zaman sizin yararınıza çalışır:

biz bilinen
var q = Context.Foos.Where(p => p.f1 == "foo" && p.f2 == "bar"). 
      ToList().Where(s => s.Bar.ToLower().Contains("hi")); 
+1

Bu, Linq to Entities: amaç uygun bir SQL talebi oluşturmaktır. Çözümünüz, tablonun tüm satırlarını (veya diğer ölçütlerle filtrelenen satırları) toplayacak ve ardından filtreyi uygulayacaktır. Gerçekten bu kesinlikle verimli değil :). Ama bunun işe yarayacağını itiraf ediyorum! –

+1

Hedefin varlıklar için uygun bir linq olduğunu düşündüm? Verimlilik açısından ... Bazen, müşteriniz lanet böcekleri düzeltmek için çığlık attığında ve patronunuz parmaklarını vurarak size göz kırpıyor ... Verimlilik ve performans, olmadıkları durumlar haricinde fazlasıyla abartılıyor. Sadece bir şey optimize edilebileceği için olması gerektiği anlamına gelmez. –

+2

Anlaştık, bu tekniği kullanan yeni insanların gerçekten ne yaptığını bilmelerini istedim (L2E'yi kaç kişinin altında ne olduğunu bilmeden kullandığını görmek beni şaşırttı). Dolayısıyla büyük masalarda, önemli bir performans/hafıza etkisi olabilir. Benim durumumda, performans önemli değildi. –

0

, bu çok "dinlenmişti" durumudur. ve beni çok rahatsız ediyor.

Bugün ben gibi bir görünüm oluşturmaya karar:

select * theColumn '% anahtar%' gibi

sonra EF'nin içine bu görüşü yüklemek tabloismi dan.

Hayat kolaylaşıyor!