2012-10-15 16 views
5

मैं इस पुस्तक में Redgate ftp://support.red-gate.com/ebooks/under-the-hood-of-net-memory-management-part1.pdfक्या कॉल के भीतर नामित विधि को कॉल करना संभव है?

से इस नि: शुल्क ई-पुस्तक से Linq के कुछ प्रदर्शन निहितार्थ को समझने के लिए पेज 157-158 पर कोशिश कर रहा हूँ, वे उदाहरण निम्नलिखित बनाया।

Order[] pastDueAccounts = null; 
DateTimedueDate = DateTime.Today.AddDays(-7); 
using(varcontext = new Context())  
{ 
    pastDueAccounts = context.Accounts.Where(account => account.DueDate < dueDate).ToArray(); 
} 

वे तो समारोह निम्नलिखित में फिर से शामिल होती lamda अभिव्यक्ति का हिस्सा है।

public bool PastDueAccount(Account account) 
{ 
    return account.DueDate < DateTime.Today.AddDays(-7); 
} 

अंततः उन्होंने इस कार्य को निम्नानुसार उपयोग किया।

Order[] pastDueAccounts = null; 
using(varcontext = new Context()) 
{ 
    pastDueAccounts = context.Accounts.Where(account => PastDueAccount(account)).ToArray(); 
} 

के आधार पर मैं क्या शोध अब तक, LINQ के रूप में अपनी इस LINQ क्वेरी चलाने के लिए संभव नहीं विधि की पहचान नहीं कर सकेंगे और एक दुकान अभिव्यक्ति में अनुवाद कर जा सकता है। मुझे आश्चर्य है कि क्या यह उदाहरण गलत है और चलाने के लिए संभव नहीं है या अगर मुझे इस समस्या को अनुकरण करने के तरीके के बारे में सुनाई देने में मुश्किल हो रही है?

उत्तर

3

जैसा कि कैस्पर ने कहा, आप इसे किसी फ़ंक्शन के साथ नहीं कर सकते हैं। यह उत्तर ऐसा करने का एक तरीका है जिसे आपको करने की आवश्यकता है (जहां फ़िल्टर फ़िल्टर करें)।

आप कहीं भी Expression बना सकते हैं, फिर आप इसका उपयोग कर सकते हैं।

System.Linq.Expressions.Expression<Func<Account, bool>> pastDueAccountFunc = account => account.DueDate < System.Data.Objects.EntityFunctions.AddDays(DateTime.Now, -7);

फिर बाद में इसका इस्तेमाल करने की:

System.Linq.Expressions.Expression<Func<SomeNeatEntity, bool>> func = x => x.DateCreated < System.Data.Objects.EntityFunctions.AddDays(DateTime.Now, -7); 

var entities = new MyEntities(); 

var t = entities.SomeNeatEntities.Where(func); 
Console.WriteLine(t.Count()); 

var h = entities.SomeNeatEntities.Where(x => x.SomeField != null).Where(func); 
Console.WriteLine(h.Count()); 

MyEntities परियोजना में ObjectContext है:

var pastDueAccounts = context.Accounts.Where(pastDueAccountFunc);

यह पूर्ण कोड मैं इस के साथ उपयोग कर रहा हूँ है ।
entities.SomeNeatEntitiesObjectSet<SomeNeatEntity> है।

+0

यह गलत है, और काम नहीं करेगा, क्योंकि यह लैम्ब्डा-अभिव्यक्ति नहीं है और क्वेरी प्रदाता द्वारा मूल्यांकन नहीं किया जा सकता है। – casperOne

+0

मुझे सचमुच यह एक ईएफ सेटअप के खिलाफ काम कर रहा है। – Gromer

+3

यदि यह काम कर रहा है, तो आप * क्लाइंट * पर फ़िल्टर कर रहे हैं और 'कहां' को 'IENumerable ' से परिणामों का मूल्यांकन कर रहा है और * नहीं * सर्वर को तरफ फ़िल्टर का अनुवाद कर रहा है। याद रखें, 'IQueryable ' 'IENumerable ' से प्राप्त होता है, इसलिए 'IENumerable ' पर सभी एक्सटेंशन विधियां 'IQueryable 'पर काम करेंगी और यह हमेशा स्पष्ट नहीं है कि संक्रमण कब होता है। – casperOne

8

आप सही हैं, यह LINQ-to-Entities द्वारा प्रदर्शित होने के तरीके से नहीं कहा जा सकता है।

एक ही तरीका है उस में इस्तेमाल किया जा सकता LINQ करने वाली संस्थाओं के लिए है:

  • सर्वर साइड पर समारोह के बराबर बनाएँ।
  • Map the function in the model उचित रूप से ताकि यह सही ढंग से कॉल का अनुवाद कर सके।
+0

LINQKit के 'AsExpandable()' का उपयोग करना एक और विकल्प है जहां आप अभिव्यक्ति विधियों का उपयोग कर सकते हैं जिन्हें SQL में अनुवाद करने में सक्षम हैं। – Ocelot20

+0

@casperOne: जहां पर टीएस और एच के लिए बुलाया जाता है, वहां वीएसएनईटी में कहां पर होवर करने पर आपकी टिप्पणी के बारे में, यह कहां निर्धारित करता है कि कहां कॉल करना है INumerable के साथ कहां और कॉल करने के लिए कहां IQueryable के साथ? –

+0

@palmsnow मूल रूप से टाइप करें अनुमान सबसे अच्छा फिट निर्धारित करता है। इस विशेष मामले में, चूंकि पैरामीटर एक 'Func ' है और 'अभिव्यक्ति >' यह 'क्वेरी करने योग्य नहीं है। वहां' (जो अभिव्यक्ति लेता है), केवल 'संख्यात्मक। वहाँ' (जो कि ' एक प्रतिनिधि लेता है)। – casperOne

संबंधित मुद्दे