简体   繁体   中英

How to pass (and return) LINQ IQueryable<T> to a Function?

I'd like the ability to pass (and return) an IQueryable<T> to a function for adding expression logic:

public void getShips()
{
    var shipyard =
        from ship in db.Ships
        select new { ship };

    var ballerShips = GetExpensiveShips(shipyard);     
}

public IQueryable<T> GetExpensiveShips<T>(IQueryable<T> query)
{
    return query.Where(q => q.NetValue > 150000); // <== Error CS1061
}

Returns this error:

Error   CS1061  'T' does not contain a definition for 'NetValue' and no
extension method 'NetValue' accepting a first argument of type 'T' could be 
found (are you missing a using directive or an assembly reference?

I've tried defining an Interface for shipyard and adding where T : IShipyard but that seems to cause more problems and leads to substantial boilerplate.

I would also like to avoid executing the SQL till after passing through my function.

Is this possible?

You need to remove some unnecessary complexity.

Change the last line of your query to:

select ship;

And then change your method declaration to:

public IQueryable<Ship> GetExpensiveShips(IQueryable<Ship> query)

Your method is already written so that it will only work on Ship instances - it uses the Ship.NetValue property. So, you need to be explicit that that's the type it should take. There's no need for this method to be generic.

You need something, that contains NetValue property. T is generic type without properties. So, adding an interface is right way:

interface IShip
{
    int NetValue {get;}
}

class Ship : IShip
{
    public int NetValue {get;set;}
}

public IQueryable<T> GetExpensiveShips<T>(IQueryable<T> query)
    where T : IShip, class
{
    return query.Where(q => q.NetValue > 150000);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM