2010-12-11 8 views
7

में नहीं [संपादित करें: मैंने समस्या को पुन: उत्पन्न करने के लिए कुछ और संदर्भ और कोड के साथ नीचे मूल प्रश्न छोड़ा है। नीचे लघु संस्करण सवाल का सार] शामिलईएफ 4: LINQ 2 इकाइयां क्वेरी सी # में काम करती हैं लेकिन वीबी

लघु संस्करण: "प्रकार 'System.Linq.IOrderedQueryable 1' to type 'System.Linq.IQueryable 1' LINQ संस्थाओं केवल इकाई कास्टिंग का समर्थन करता है के लिए कास्ट करने में असमर्थ:। नीचे दिए गए क्वेरी एक System.NotSupportedException फेंकता डेटा मॉडल आदिम प्रकार। " अपवाद केवल VB.Net संस्करण में उठाया गया है। जब सी # में अनुवाद किया जाता है, तो कोई अपवाद नहीं उठाया जाता है।

Dim doesThisCrash = From outerOrder In orders 
     Where outerOrder.ProductId = 
     (From p In products Join o In orders On p.Id Equals o.ProductId 
     Order By p.Id 
     Select p.Id).FirstOrDefault() 
     Select outerOrder 
    doesThisCrash.ToList() 

इसलिए, यह दुर्घटना बनाने के लिए, ऐसा लगता है कि हम एक सबक्वेरी जहां मूल ObjectSet (आदेश) एक और ObjectSet (उत्पाद) के साथ शामिल हो जाता है, और आदेश दिया की जरूरत है। ऑर्डर या उत्पादों को सेट करते समय, कोई क्रैश नहीं होता है। आदेश छोड़कर, कोई दुर्घटना भी नहीं।

मुझे लगता है कि यह एक (VB.Net) संकलक बग है, जब तक कि वहाँ कुछ स्पष्ट है कि मैं यहाँ अनदेखी कर रहा हूँ है इच्छुक हूँ ...

अभी के लिए मेरे सवाल अभी भी खड़ा है:

  • सी # में एक समान सटीक वही क्वेरी क्यों काम करती है लेकिन वीबी में नहीं?
  • क्या यह प्रश्न VB.Net में काम करने के लिए किया जा सकता है?

[/ संपादित करें]

वैकल्पिक, लंबे समय तक संस्करण (मूल प्रश्न):

मेरे डोमेन बहुत अलग लग रहा है, लेकिन मैं एक सरल संस्करण के लिए समस्या अनुवाद, निम्नलिखित संस्थाओं (नोट के साथ: मैं वास्तव में इन .edmx डिजाइनर का उपयोग करके परिभाषित है, तो यह एक सरलीकृत संस्करण) है:

public class Product 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public DateTime DateCreated { get; set; } 
    } 

    public class Order 
    { 
     public int Id { get; set; } 
     public int CustomerId { get; set; } 
     public int ProductId { get; set; } 
     public DateTime OrderDate { get; set; } 
    } 

    public class Customer 
    { 
     public int Id { get; set; } 
    } 

मैं, एक LINQ करने वाली संस्थाओं क्वेरी कि strucurally इस तरह दिखना चाहिए बाहर काम करने के कोशिश कर रहा हूँ VB.Net :

Dim db = New SampleEntities() 
    Dim orders As IQueryable(Of Order) = db.Orders 
    Dim products As IQueryable(Of Product) = db.Products 
    Dim currentDate = DateTime.Now 

    Dim qLinq = From outerOrder In orders 
       Where outerOrder.OrderDate = currentDate AndAlso 
       outerOrder.ProductId = 
        (From p In products Join o In orders On p.Id Equals o.ProductId 
        Where o.OrderDate = outerOrder.OrderDate AndAlso 
          outerOrder.CustomerId = o.CustomerId 
        Order By p.DateCreated 
        Select p.Id).FirstOrDefault() 
       Select outerOrder 

यह एक System.NotSupportedException को जन्म देती है:

"प्रकार 'System.Linq.IOrderedQueryable 1' to type 'System.Linq.IQueryable 1' कास्ट करने में असमर्थ। LINQ संस्थाओं के लिए एक ही कास्टिंग का समर्थन करता है इकाई डेटा मॉडल आदिम प्रकार। "

जब 'आदेश तक' भाग बाहर छोड़ रहा है, कोई अपवाद नहीं उठाया जाता है।

मैं वास्तव में एक कारण नहीं दिख रहा है यही कारण है कि इस क्वेरी नहीं होगा समर्थित ... तो मैं सी # में एक ही बात की कोशिश करने का फैसला किया: मेरे आश्चर्य करने के लिए

var qLinq = from oOut in orders 
      where oOut.OrderDate == currentDate 
        && oOut.ProductId == 
          (from p in products join o in orders on p.Id equals o.ProductId 
          where oOut.OrderDate == o.OrderDate 
          && oOut.CustomerId == o.CustomerId 
          orderby p.DateCreated 
          select p.Id).FirstOrDefault() 
        select oOut; 

, इस काम करता है तो मैं विस्तार विधि वाक्य रचना करने के लिए सी # क्वेरी अनुवाद, और फिर वापस वीबी करने के लिए, लेकिन एक ही मिला परिणाम (सी # संस्करण काम करता है, वीबी.Net संस्करण एक ही अपवाद उठाता है)

तो मैं मेरे सवाल का अनुमान है दुगना:

  • क्यों करता है सी # में नहीं बल्कि VB में एक उचित रूप में ठीक उसी क्वेरी काम करता है?
  • क्या यह प्रश्न VB.Net में काम करने के लिए किया जा सकता है?

संदर्भ के लिए, विस्तार विधि वाक्य रचना में प्रश्नों हैं:

सी # संस्करण:

 var q = orders.Where(outerOrder => 
      outerOrder.OrderDate == currentDate && 
      outerOrder.ProductId == 
      (products 
       .Join(orders, 
        f => f.Id, 
        o => o.ProductId, 
        (f, o) => new { f, o }) 
       .Where(t => t.o.OrderDate == outerOrder.OrderDate 
          && outerOrder.CustomerId == t.o.CustomerId) 
       .OrderByDescending(t => t.f.DateCreated) 
       .Select(t => t.f.Id)) 
       .FirstOrDefault()); 

VB.Net संस्करण:

Dim q = orders.Where(Function(outerOrder) outerOrder.OrderDate = currentDate AndAlso 
          outerOrder.ProductId = (products.Join(orders, 
           Function(p) p.Id, 
           Function(o) o.ProductId, 
           Function(p, o) New With {.p = p, .o = o}). 
          Where(Function(x) x.o.OrderDate = outerOrder.OrderDate AndAlso 
            outerOrder.CustomerId = x.o.CustomerId). 
          OrderByDescending(Function(x) x.p.DateCreated). 
          Select(Function(x) x.p.Id). 
          FirstOrDefault())) 
+0

एक बड़ा कोड यह इनाम की जरूरत है उस पर समय बिताने के लिए है :) –

+0

यह SampleEntities की वीबी संस्करण देखने के लिए – dbasnett

+0

@dbasnett मैं केवल इस्तेमाल किया सी # डोमेन वर्णन करने के लिए अच्छा होगा, वास्तव में मैं बनाया का इस्तेमाल किया ईएफ कोड-पीढ़ी की सुविधा में। यह गुणों के साथ बस कुछ वर्ग है। – jeroenh

उत्तर

1

अनुसार Order By p.DateCreated लाइन चलती मेरा संपादित उत्तर क्वेरी को बिना किसी अपवाद के चलाने की अनुमति देता है। हालांकि, उत्सर्जित एसक्यूएल अलग है इसलिए मुझे नहीं लगता कि आप सही परिणाम प्राप्त कर रहे हैं।

Dim qLinq = From outerOrder In orders 
      Let id = (From p In products 
         Order By p.DateCreated 
         Join o In orders On p.Id Equals o.ProductId 
         Where o.OrderDate = outerOrder.OrderDate AndAlso 
          outerOrder.CustomerId = o.CustomerId 
         Select p.Id).FirstOrDefault() 
      Where outerOrder.OrderDate = currentDate AndAlso 
        outerOrder.ProductId = id 
      Select outerOrder 
+0

आपका संशोधित उत्तर पहले काम किया गया था। मुझे अभी भी विश्वास है कि यह वीबी कंपाइलर में भी एक बग है, लेकिन मैं आपको सही उत्तर के साथ पहले व्यक्ति होने के लिए बक्षीस दे रहा हूं। अगर मैं दूसरों के साथ बक्षीस साझा कर सकता हूं, तो मैं ऐसा करता हूं क्योंकि सभी समाधान चाल करते हैं। – jeroenh

-4

हाय यह काफी आसान काम करने के लिए बनाया जा सकता है ...

एक IQueryable

Dim orders As IQueryable(Of Order) = db.Orders

के बजाय

का प्रयोग कर एक सूची

Dim orders as List(of Order) = db.Orders.ToList() 
+3

क्षमा करें, लेकिन यह एक भयानक विचार है। Db.Orders.ToList() को कॉल करके, आप ऑर्डर तालिका की पूरी तरह से स्मृति में पढ़ रहे हैं और फिर क्वेरीक करने के लिए LINQ-to-Objects का उपयोग कर रहे हैं। –

+0

जेम्स कोवाक्स से सहमत हुए। बुरा विचार। क्या होगा यदि तालिका में लाखों रिकॉर्ड हैं ?? – jeroenh

+0

लेकिन यह काम करता है :) नहीं, आप लोग सही हैं, –

2

मुझे लगता है कि निम्नलिखित कार्यों, एसक्यूएल बदसूरत है हालांकि:

Dim qLinq = From outerOrder In orders 
       Where outerOrder.OrderDate = currentDate AndAlso 
       outerOrder.ProductId = 
        (From x In (From p In products 
           Join o In orders On p.Id Equals o.ProductId 
           Where o.OrderDate = outerOrder.OrderDate AndAlso 
             outerOrder.CustomerId = o.CustomerId 
           Select p.Id) 
        Order By x).FirstOrDefault() 
       Select outerOrder 
+0

के बारे में सोचा नहीं था आपका उत्तर भी काम करता है। अगर मैं कर सकता, तो मैं कुछ बक्षीस साझा करता, लेकिन हां यह संभव नहीं है ... – jeroenh

2

क्या यह काम करता है?

Dim a = From p In products Join o In orders On p.Id Equals o.ProductId 
      Order By p.DateCreated 
      Select New With {.id = p.Id, .OrderDate = o.OrderDate, .CustomerId = o.CustomerId, .DateCreated = p.DateCreated} 

    Dim b = From outerOrder In orders _ 
      Where outerOrder.OrderDate = currentDate _ 
      AndAlso outerOrder.ProductId = _ 
      (From x In a Where x.OrderDate = outerOrder.OrderDate _ 
      AndAlso x.CustomerId = outerOrder.CustomerId _ 
      Select x.id).FirstOrDefault 
+0

आपका उत्तर भी काम करता है। अगर मैं कर सकता, तो मैं कुछ बक्षीस साझा करता, लेकिन हां यह संभव नहीं है ... – jeroenh

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