2010-04-20 17 views
9

Bu çalışır:LINQ-to-Entites neden özel yöntemimi tanıdı?

Entities.WorkOrderSet.Where(MyCustomMethod); 

Bu değildir:

Entities.WorkOrderSet.Where(o => MyCustomMethod(o)); 

([Düzenle] bile new olmadan, çalışmıyor)

anlıyorum neden ikinci çalışmıyor - ama dünyada neden ilk iş yapıyor !?"LINQ-to-Entities yöntemini tanımıyor mu?" çalışma zamanında, ikincisinde olduğu gibi mi? Referans için

, burada, EF4'ü olmayan EF1 kullanarak MyCustomMethod

public bool MyCustomMethod(WorkOrder workOrder) 
{ 
    return !workOrder.WorkOrderNum.StartsWith("A", StringComparison.CurrentCultureIgnoreCase); 
} 

olan

+0

İkincisini çalıştırmaya çalıştığınızda hangi istisna var? –

+0

Ayrıca, EF'in ilk sehpanızı çalıştırdığınızda tüm tabloyu almamasını ve işlevi yerel olarak çalıştırdığından emin misiniz? SQL profiler dosyasını çalıştırın ve sunucuya hangi sorgunun gönderildiğini kontrol edin. –

+0

"LINQ-To-Entities yöntemi tanıyamaz ..." - Bu, beklenen davranış, özel yöntemler SQL'e çevrilemediğinden dolayı. Her zamanki çözüm, önce .ToList() 'i çağırmaktır ... ama bir sebepten ötürü, o olmadan çalışıyormuş gibi görünüyor! –

cevap

6
bu daha sonra bir uzantı yöntemi olup bir fonksiyon olarak sorgu yürütülürken olduğu, ve birinci işleri

Listenizi filtrelemek see here. Yani genel olarak otomatik

Where(Func<WorkOrder, bool> 

İkinci etmek yerde döküm ediyorum o db'ye aşağı nerede deyimi bastırıyor değil çünkü. lambda ifadesi değerlendirildiğinde böyle genişletilir: Burada

Where(Expresion<Func<WorkOrder, bool>>) 

Func vs Expressions açıklayan iyi bir article olduğunu

Here is another SO post that helps to explain the difference

[Düzenle (BlueRaja)]

Bu yeni düzenleme doğru görünüyor. Açıklığa kavuşturmak için: Func<WorkOrder, bool>'un örtülü olarak Expression<Func<WorkOrder, bool>>'a bağlı olduğu görülüyor, ancak başka bir yol değil.

Her iki tip için de Where aşırı yüklenme var. .Where(MyCustomMethod), Func<WorkOrder, bool> birimini çağırıyor, .Where(o => MyCustomMethod(o)) ise Expression<Func<WorkOrder, bool>> birini çağırıyor.

+1

Lütfen tekrar kontrol edin. Anonim bir sınıf kullanıyor olabilir, ancak özel yöntemi hala bir WorkOrder nesnesini parametre olarak alırken, kodunuz bile derlenmeyecektir :) –

+0

Belki de ayrıntılandırmalıyım (yukarıdaki düzenlemeye bakın): kod derler, ancak çalışma zamanı sırasında * başarısız olur. "Varlıkların LINQ, yöntemi tanımıyor ..." * Örnek: http://blog.dreamlabsolutions.com/post/2008/11/17/LINQ-Method- -de-bir-store-expression.aspx içine tercüme edilemez Bu beklenen, ancak ilk iş YAPILIR olması gerçeği beklenmedik! –

+0

@Nix tekrar bakın: P yeni {WorkOrder = o} aslında anonim bir sınıftır ... Inside .Where (o => ...) o anonim sınıftır .. o.WorkOrder WorkOrder türündeyken .. Bu durumda fonksiyonuna geçirilen parametre doğru tipte! –

1

Onun yerine bir yorumun, burada bir "yanıt" olarak bu şekillendirme ..

Ben, bu çerçeve bu fonksiyon SQL tercüme edilemez olduğunu fark .NET 4, yeni bir özelliktir olduğunu düşünüyorum ama bellekte kolayca işlenebilir. Böylece tüm veri kümesini yerel makineye alır ve sorgulama işlemine devam eder.

İlk snippet'iniz, bir ifade ağacına çevrildiğinde, doğrudan bir dış yöntem çalıştırdığını söyler, ikinci snippet'iniz ise o kadar "doğrudan" değil. İlk durumda L2E'nin ne olup bittiğini kolayca anlayabildiğini ve ne yapacağına karar verebildiğini düşünürken, ikinci durumda “düşünür” bir istisna göndermek ve geliştiricilerin kafalarını biraz daha kazıya bırakması daha iyidir^_^

+0

EF1 kullanarak. Net 3.5 –

+0

belki de o zaman bir EF1 vs L2S 1 şey nedir? Ya da belki şimdi bir süredir var olan bir özellik var mı? Her ne ise - en iyi açıklama, çerçevenin, sorgulamanızın derlendiği ifade ağacına dayanarak akıllı olmaya çalışıyor olmasıdır :) –

İlgili konular