none
How to pass the results of a Linq query to a function in VB RRS feed

  • Question

  • Can anyone provide an example or references on how to pass the reuslts of a Linq query to a function in Visual Basic?  Specifically, I am having problems with the argument signature on the receiving end (in the Sub or Function).

    My Linq query includes both string and numeric elements of a typed class,  but I think the query itself is generic and I'm not exactly sure how to present the data to the reciving function.  What I'm interested in are the latitude and longitude values (which need to be tested for dbnull).  I can pass the entire query as a queryable, or iterate over the query and isolate the Lat/Lon values as numeric arrays, but I'm not sure this is necessary?

    If I call the function as follows, what is the appropriate signature on the function and how do I access the passed Lat/Lon elements in the function?

         chkLatLon(myQuery)

         private function chkLatLon(myQuery as queryable) 'not sure about signature???

    Any guidance would be appreciated.  Thanks -BGood

     

    Wednesday, May 19, 2010 3:22 PM

Answers

  • Hi BGood,

     

    For anonymous types, here are a great remark in MSDN document: http://msdn.microsoft.com/en-us/library/bb397696.aspx.

    “An anonymous type has method scope. To pass an anonymous type, or a collection that contains anonymous types, outside a method boundary, you must first cast the type to object. However, this defeats the strong typing of the anonymous type. If you must store your query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.

     

    So, could you create some ordinary named struct or class to handle it in your app?  

     

     

    For the “explicit construction” issue, I think it is a LINQ to SQL query where the runtime exception throws, right?   To make it work, we can first convert make the LINQ to SQL IQueryable<> query as IEnumerable<>, so the latter query becomes LINQ to Objects query, which of course supports the “explicit construction”:

    ======================================================================================

    Dim mquery = (From r in myTable Where … _
                             Select r).AsEnumerable()

                             .Select(Function(r) New mappedComps With { .property1 = r.prop1, … })

    ======================================================================================

    Does it work for you?   

     

    Have a nice day!

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, May 25, 2010 3:34 AM
    Moderator

All replies

  • I am sorry I do not know VB, but in C# I pass IEnumerable<T> around to delay execution.
    Wednesday, May 19, 2010 7:31 PM
  • Thanks LitEnders.  I've seen that C# synatax, but in VB does that translate to:

         chkLatLon(myQuery)

         private function chkLatLon(myQuery as IEnumerable(of T))

    I'm still not sure about the function's signature.

     

         -BGood

    Thursday, May 20, 2010 2:48 AM
  • Hello BGood,

     

    Welcome to LINQ to SQL forum!

     

    What’s the type of the generic type T in your scenario?   You have mentioned that you have a typed class which contains both string and numeric elements.   Do you mean your IQueryable(Of T) query can obtain both string and numeric values synchronously, like { “Hello”, 123, “World”, “100” }?   Do you want such a Function declaration? 

    =============================================================================

    Sub MyQuery(ByVal query As IQueryable(Of Object))

     

    End Sub

    =============================================================================

    If it does not solve the problem, could you please provide us with more detailed information of your scenario?  

     

    Have a nice day!

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Thursday, May 20, 2010 8:44 AM
    Moderator
  • Hi Lingzhi,

    Thanks for the reply.  I have tried both anonymous and typed signatures. The class I designed for the query is "mappedComps" and includes elements for both string (Address), and numeric (Latitude, Longitude, etc).  The following call and signature compile OK, but give me an invalid cast in the subroutine:

         reference:     mySub(myQuery)

         signature:     Private Sub mySub(ByVal query as iQueryable(of mappedComp)

    I assume I must be doing something wrong in the query itself so that the query does not match the schema or type of my class.  A generic approach also compiles, but I don't know how to extract the elements of the query in the subroutine:

         reference:     mySub(myQuery)

         signature:     Private Sub mySub(ByVal query as iQueryable())

    It would be helpful to know how to extract elements from the query in the subroutine when the query is passed via a generic iQueryable argument.

    Thanks again for your help.

         -BGood

    Thursday, May 20, 2010 3:06 PM
  • Hello BGood,

     

    You are weclome!    Could you please provide more information about the "Invalid Cast" exception?     Maybe I can share some idea on it.  :-)  

     

    Have a nice day!

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, May 21, 2010 3:05 AM
    Moderator
  • Hi Lingzhi,

    What I have been looking for is a way to re-use strongly-typed projections from Linq queries, but from my research, it seems that the Linq developers intentionally limited the ability of Linq queries to project into strongly-typed objects to limit the complexity of object-tracking objects created on-the-fly via Linq queries. 

    So I'm not sure if it is possible for me to accomplish what I want to do.  I was hoping to "pass around" Linq query results as  arguments to subroutines and functions. 

    Scoping was the first problem I encountered.  When the Linq results were used locally (dim q = from ...) , intellisense is able to infer the property names within the queryable (q).  But when the Linq query is out of scope, the properties are not visible.

    So I tried broadening the scope of the queryable result by declaring it at module or class level (Public q as queryable()), but this is an anonymous type which does not help with property identification elsewhere in the program.  Making the class-level delcaration strongly-typed (Public q as queryable(of myType) solves this problem, but I get the following run-time exception when the projetion is attempted (indentation of the error message is edited to help match up the typing of my public object properties (integer ID, integer, 3 strings, 4 decimals, string) which appear to match):

    Unable to cast object of type
        System.Data.Linq.DataQuery`1[VB$AnonymousType_5
              `10[System.Int32,System.Nullable
              `1[System.Int32],System.String,
              System.String,
              System.String,
              System.Decimal,
              System.Decimal,
              System.Decimal,
              System.Decimal,
              System.String]]' 
        to type 'System.Collections.IEnumerable[]'.

    While I cannot publicly publish the actual code, I wonder if you could guide me to an understandable method of providing strong typing to the results of an anonymous linq query? 

    When I try to explicitly type the query projection (mquery as mappedComps) using a select clause like this:

    dim mquery = (from r in myTable where ...
               Select New mappedComps With {
              .property1=r.prop1, .property2=r.prop2, etc}).asEnumerable

    I get a different run-time error: "Explicit construction of entity type 'cds.mappedComps' in query is not allowed.

    So, Is there any way to do this?

         Thanks, -BGood

     

     

    Monday, May 24, 2010 11:35 PM
  • Hi BGood,

     

    For anonymous types, here are a great remark in MSDN document: http://msdn.microsoft.com/en-us/library/bb397696.aspx.

    “An anonymous type has method scope. To pass an anonymous type, or a collection that contains anonymous types, outside a method boundary, you must first cast the type to object. However, this defeats the strong typing of the anonymous type. If you must store your query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.

     

    So, could you create some ordinary named struct or class to handle it in your app?  

     

     

    For the “explicit construction” issue, I think it is a LINQ to SQL query where the runtime exception throws, right?   To make it work, we can first convert make the LINQ to SQL IQueryable<> query as IEnumerable<>, so the latter query becomes LINQ to Objects query, which of course supports the “explicit construction”:

    ======================================================================================

    Dim mquery = (From r in myTable Where … _
                             Select r).AsEnumerable()

                             .Select(Function(r) New mappedComps With { .property1 = r.prop1, … })

    ======================================================================================

    Does it work for you?   

     

    Have a nice day!

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, May 25, 2010 3:34 AM
    Moderator
  • Hi Lingzhi,

    I'll give it a try.  Thanks for the research.

        -BGood

    Tuesday, May 25, 2010 4:13 AM
  • Thank you sooooo much, that worked a treat :-)
    Thursday, January 5, 2012 2:28 PM