none
How to get Dynamic LINQ working with VS 2010 RRS feed

  • Question

  • I downloaded the dynamic LINQ classes here http://msdn.microsoft.com/en-us/vbasic/bb964686.aspx but when I include the class DynamicLinq.vb in my data access class library every reference to System.Data produces an error inside my Entity class definitions saying the Data is not a member of System.  I remove this class and the erros go away and everything is normal.  Is there an updated version of this that is compatible with VS 2010?

    All I want to do is specify the type of the querable object dynamically.  For example this is the code I have to use right now - the typesafe version which I have to encode a select case to specify the types:

     

     

    'Populate data grid with rates of selected Surcharge row

     

     

    Dim c As DataAccess.FuelSurchargeRate

     

     

    Dim cid As Int32 = CInt(dgSurcharges.Item("Id", dgSurcharges.CurrentRow.Index).Value)

    c = (

     

    From cm In ctx.CompanyRates.OfType(Of DataAccess.FuelSurchargeRate)() Where cm.Id = cid Select cm).First()

    dgSurchargeRates.DataSource = c

    What I want to do is:

    c = (

     

    From cm In ctx.CompanyRates.OfType("Value of Class TypeName in selected row of dgSurcharges")() Where cm.Id = cid Select cm).First()

    dgSurchargeRates.DataSource = c

     

    Any ideas?

     

    Thanks,


    Carey

    Friday, February 11, 2011 4:29 AM

Answers

  • Hi Carey,

    Welcome to MSDN forum!

    The compiler issue you encountered does not occur only in VS2010 since it's a VB.NET project specific issue.   The detailed reason can be found here, http://stevescodingblog.co.uk/vb-dynamic-query-library-woes/.  

    The solution is:  1)  Remove the default namespace for your class library project.   2)  Or remove or edit the namespace for the Dynamic.vb.  (Note:  Several "System.Linq.Dynamic.Signature" are used in the class, so we need to edit the namespace accordingly)

     

    For the dynamic OfType you want, I don't think the Dynamic LINQ Library supports it.  But I once created a similar OfType extension method to extend the library here, http://social.msdn.microsoft.com/Forums/en/linqtosql/thread/fbfa7e59-e97f-4d34-9810-5dbf6b8f444c.  

    I modified it to VB.NET here for your references and it is added into the Dynamic.vb
    ==============================================================
    Namespace System.Linq.Dynamic
        Public Module DynamicQueryable

            <Extension()> _
            Public Function OfType(Of T)(ByVal source As IQueryable(Of T), ByVal typeStr As String) As IQueryable
                If (source Is Nothing) Then
                    Throw New ArgumentNullException("source")
                End If
                If (typeStr Is Nothing) Then
                    Throw New ArgumentNullException("typeStr")
                End If

                Dim type = Assembly.GetExecutingAssembly().GetType(typeStr)
                Dim methodOfType = GetType(Queryable).GetMethods().First(
                    Function(m) m.Name = "OfType" And m.IsGenericMethod)

                Return source.Provider.CreateQuery( _
                    Expression.Call(Nothing, methodOfType.MakeGenericMethod(New Type() {type}), New Expression() {source.Expression}))

            End Function
    ==============================================================

    If you have any questions, please feel free to let me know.

    Have a nice weekend!

    Thanks


    Michael Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by CareyB Monday, February 14, 2011 5:31 AM
    Saturday, February 12, 2011 7:00 AM
    Moderator
  • Hi Carey,

    So you are using LINQ to Entities instead of LINQ to SQL, right?  

    I performed some test at my side by the following codes and it works fine.  Are you trying to cast the types with inheritance relationships?  In your codes, I think it will work fine if AdminFee inherits the type CompanyRate.   Also, I used the LINQ extension methods in my query and bind the query result to a WinForm DataGridView.
    =====================================================================
           Using context As New TestDBModel.TestDBEntities
                 Dim query = context.Users.OfType("TestDBModel.User").Where("UserID = 1")

                 DataGridView1.DataSource = query
            End Using
    =====================================================================

    Please let me know your testing results.  If you have any questions, please feel free to let me know.

    Good day!

    Thanks


    Michael Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by CareyB Monday, February 14, 2011 5:31 AM
    Monday, February 14, 2011 4:03 AM
    Moderator

All replies

  • Hi Carey,

    Welcome to MSDN forum!

    The compiler issue you encountered does not occur only in VS2010 since it's a VB.NET project specific issue.   The detailed reason can be found here, http://stevescodingblog.co.uk/vb-dynamic-query-library-woes/.  

    The solution is:  1)  Remove the default namespace for your class library project.   2)  Or remove or edit the namespace for the Dynamic.vb.  (Note:  Several "System.Linq.Dynamic.Signature" are used in the class, so we need to edit the namespace accordingly)

     

    For the dynamic OfType you want, I don't think the Dynamic LINQ Library supports it.  But I once created a similar OfType extension method to extend the library here, http://social.msdn.microsoft.com/Forums/en/linqtosql/thread/fbfa7e59-e97f-4d34-9810-5dbf6b8f444c.  

    I modified it to VB.NET here for your references and it is added into the Dynamic.vb
    ==============================================================
    Namespace System.Linq.Dynamic
        Public Module DynamicQueryable

            <Extension()> _
            Public Function OfType(Of T)(ByVal source As IQueryable(Of T), ByVal typeStr As String) As IQueryable
                If (source Is Nothing) Then
                    Throw New ArgumentNullException("source")
                End If
                If (typeStr Is Nothing) Then
                    Throw New ArgumentNullException("typeStr")
                End If

                Dim type = Assembly.GetExecutingAssembly().GetType(typeStr)
                Dim methodOfType = GetType(Queryable).GetMethods().First(
                    Function(m) m.Name = "OfType" And m.IsGenericMethod)

                Return source.Provider.CreateQuery( _
                    Expression.Call(Nothing, methodOfType.MakeGenericMethod(New Type() {type}), New Expression() {source.Expression}))

            End Function
    ==============================================================

    If you have any questions, please feel free to let me know.

    Have a nice weekend!

    Thanks


    Michael Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by CareyB Monday, February 14, 2011 5:31 AM
    Saturday, February 12, 2011 7:00 AM
    Moderator
  • Hi,

    Thanks for the update.  I inserted this function in my DyanmicLinq.vb module and removed my default namespace form my data access class library and all is well there.

    However, I changed my calling code to reflect the following:

    Dim cid As Int32 = CInt(dgSurcharges.Item("Id", dgSurcharges.CurrentRow.Index).Value)
        Dim sc As Iqueryable
        'sc = (From cm In ctx.CompanyRates.OfType(Of AdminFee)() Where cm.CompanySurchargeId = cid)
        sc = (From cm In ctx.CompanyRates.OfType("AccurateModel.AdminFee") Where ("CompanySurchargeId = " & cid))
    
        'Populate data grid with rates of selected Surcharge row
        dgSurchargeRates.DataSource = sc

    It fails on the datasource assignment to the datagridview with:

    {"Unable to cast the type 'AccurateModel.AdminFee' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types."}

    I tried changing the Dim sc As to ObjectQuery and even left it without specify type and the same error occurs.

    The execution of the dynamic query piece seems to be ok though.

    Monday, February 14, 2011 2:07 AM
  • Hi Carey,

    So you are using LINQ to Entities instead of LINQ to SQL, right?  

    I performed some test at my side by the following codes and it works fine.  Are you trying to cast the types with inheritance relationships?  In your codes, I think it will work fine if AdminFee inherits the type CompanyRate.   Also, I used the LINQ extension methods in my query and bind the query result to a WinForm DataGridView.
    =====================================================================
           Using context As New TestDBModel.TestDBEntities
                 Dim query = context.Users.OfType("TestDBModel.User").Where("UserID = 1")

                 DataGridView1.DataSource = query
            End Using
    =====================================================================

    Please let me know your testing results.  If you have any questions, please feel free to let me know.

    Good day!

    Thanks


    Michael Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by CareyB Monday, February 14, 2011 5:31 AM
    Monday, February 14, 2011 4:03 AM
    Moderator
  • Thank You!!  I was not using the syntax you have demonstrated.  I changed my code from :

    Dim sc As Iqueryable
        'sc = (From cm In ctx.CompanyRates.OfType(Of AdminFee)() Where cm.CompanySurchargeId = cid)
        sc = (From cm In ctx.CompanyRates.OfType("AccurateModel.AdminFee") Where ("CompanySurchargeId = " & cid))

    to this:

    Dim

     

     

    sc As ObjectQuery
    sc = ctx.CompanyRates.OfType("AccurateModel.AdminFee").Where("CompanySurchargeId = " & cid)
    'Populate data grid with rates of selected Surcharge row
    dgSurchargeRates.DataSource = sc

    and it works great :-)

    Monday, February 14, 2011 5:31 AM