R.D
R.D

Reputation: 4871

How to Re-Order Evaluation of this Linq Scenario

Here is a code snippet

IEnumerable<Car> GetCars()
{
   foreach(var request in RequestQueue())
   {
       RemoveFromQueue(request);
       yield return MakeCar(request);//Expensive
   }
}

//Usage Scenario 1: No Problem

foreach(Car c in GetCars())
{
//Do stuff
}

//Usage Scenario 2: Problem, I have constructed all cars, but want only 1.

foreach(Car c in GetCars().Where(p=>p.Request.Id==10000))
{
 //Do stuff
}

Is it possible to implement Evaluating the Where clause before I go ahead and make a Car? How?

Obviously, the where clause can vary based on the client usage.

Motivation: When you do Linq to SQL, .Take(10) is transformed to Top(10) and the query is executed on the server. I want to achieve something like this.

Upvotes: 0

Views: 142

Answers (2)

Erv Walter
Erv Walter

Reputation: 13788

@J.13.L's suggestion is probably the best practical one: expose an API that gets a single Car.

That said, the answer to your final question about how .Take(10) turns in to TOP 10 on the SQL server is that you have to implement an IQueryable provider and parse the expression tree. This is not very trivial, but if you are interested in learning how, there is a great series of articles about doing it here:

Upvotes: 1

bytebender
bytebender

Reputation: 7491

Not sure without seeing the rest of your code but what is stopping you from doing this?

Car GetCar(id)
{
    Car result = default(Car);

    // I am assuming that RequestQueue() is Enumerable?
    Request request = RequestQueue().SingleOrDefault(p => p.Request.Id == id);

    if(result != null)
    {
        RemoveFromQueue(request);

        result = MakeCare(request);
    }

    return result;
}

Then use this method instead of GetCar() and //Do Something, but it's difficult to know if this would work without seeing more of the code. Hope this helps...

Upvotes: 0

Related Questions