locked
Bind webgrid to EF query result - Error_7_Argument 1: cannot convert from 'ProviderRxTransaction' to 'System.Collections.Generic.IEnumerable<dynamic>' RRS feed

  • Question

  • User379720387 posted

    This is the equivalent of a db.QuerySingle:

    var rx1 = dbContext.ProviderRxTransactions
            .Include("ProviderService.Service")
            .Where(t => t.transactionId == transactionid).FirstOrDefault();

    var grid = new WebGrid(rx1, rowsPerPage: 20);

    How can I bind the webgrid to rx1?

    Monday, October 17, 2016 1:07 AM

Answers

  • User-821857111 posted

    The WebGrid is designed to display collections as rows of data. Your query only returns a single object. If you really want to use the grid to display details of one object change the query to return a collection:

    var rx1 = dbContext.ProviderRxTransactions
            .Include("ProviderService.Service")
            .Where(t => t.transactionId == transactionid).ToList();

    Obviously if more than one item has the same transactionId, they will be displayed too. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, October 17, 2016 6:23 AM

All replies

  • User-821857111 posted

    The WebGrid is designed to display collections as rows of data. Your query only returns a single object. If you really want to use the grid to display details of one object change the query to return a collection:

    var rx1 = dbContext.ProviderRxTransactions
            .Include("ProviderService.Service")
            .Where(t => t.transactionId == transactionid).ToList();

    Obviously if more than one item has the same transactionId, they will be displayed too. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, October 17, 2016 6:23 AM
  • User-691209617 posted

    The simplest fix is just to use the Cast<> LINQ operator:


    public IEnumerable<IMyType> All() {
    var query = _connection.Query("SELECT * FROM [table]");
    return query.Select(o => _myTypeFactory.Create(o))
    .Cast<IMyType>();
    }


    Alternatively, you could cast each element:
    public IEnumerable<IMyType> All() {
    var query = _connection.Query("SELECT * FROM [table]");
    return query.Select(o => (IMyType) _myTypeFactory.Create(o));
    }


    It doesn't currently work because there's simply no implicit conversion available between IEnumerable<dynamic> and IEnumerable<IMyType>. IEnumerable<dynamic> could be implemented in any number of ways, and given that each item will be generated dynamically there's no reason to suppose the result value will implement IEnumerable<IMyType>.

    I agree that it looks like the second form isn't actually adding anything, but the compiler doesn't check all the possible return types of _myTypeFactory.Create(o) - it treats that whole expression as a dynamic value, i.e. the expression is of type dynamic. Therefore the Select result is still of type IEnumerable<dynamic>.

    Another option is to specify the generic type argument to Select.

    public IEnumerable<IMyType> All() {
    var query = _connection.Query("SELECT * FROM [table]");
    return query.Select<IMyType>(o => _myTypeFactory.Create(o));
    }
    That's attempting to force the lambda expression to a Func<dynamic, IMyType> - I believe that will work...

    Monday, October 17, 2016 1:01 PM
  • User-821857111 posted

    The simplest fix is just to use the Cast<> LINQ operator:
    Huh??? What question are you answering?

    Monday, October 17, 2016 6:45 PM