user996937
user996937

Reputation: 45

merging Linq queries

Could someone explain me what will happen when I execute this query

I'm using (read learning) ninject and have following code

public interface IProducts
{
    IQueryable<Product> Products { get; }

   //some functions

}

I have following class "Product" which implements IProducts interface

public class Product
{
    public string Name { get; set; }
    public string Price { get; set; }

    public IQueryable<Product> Products
    {
        get
        {
            using(/*Connect to dtabase*/)
            {
                var products = from p in db.Products
                               select p;
            }
        }
    }
}

Now I have added

ninjectKernel.Bind<IProducts>().To<Product>();

I wonder what will happen if I have added another Linq query like where product.Name == Something

For example

public class ProductController : Controller
{
    private IProducs repository;

    public ProductController(IProducts products)
    {
         repository = products;
    }

    public ViewResult Find(string productName)
    {
          var product = from p in repository
                         where p.Name == productName
                         select p;
     }
}

Far as I know Linq query will execute only when I loop trough data so I wonder if these two Linq queries will merge into one.

For example

from p in db.Products
where p.Name == Something
select p;

Could someone confirm me if I got it right

Upvotes: 3

Views: 430

Answers (1)

Adam Ralph
Adam Ralph

Reputation: 29956

The compiler will effectively transform your declarative LINQ statements into method calls. (I say effectively because it's really down to compiler internals whether method translation actually takes place or whether it 'shortcuts' straight to IL - this is not important for us to know in this context.)

I.e. :-

from p in db.Products
    select p;

represents

db.Products.Select(p => p);

and

from p in repository.Products    // .Products is missing in your code
    where p.Name == productName
    select p

represents

repository.Products.Where(p => p.Name == productName);

Now, since execution is deferred, when we enumerate our final value ('loop through data'), the following will effectively be executed:-

db.Products.Select(x => x).Where(p => p.Name == productName);

It is then down to the specific implementation of IQueryable<T> (db.Products) to translate this to whatever is appropriate. In the case of the Linq2SQL provider, this will be something like:-

SELECT
    P.Name, P.Foo, P.Bar, ...
FROM
    Product P
WHERE
    P.Name = "the name you specify"

So you see, due to deferred execution, the translation to a single query against the database is done for you. You don't have to take any special action to make this happen.

Upvotes: 2

Related Questions