объединение запросов Linq - PullRequest
3 голосов
/ 15 октября 2011

Может ли кто-нибудь объяснить мне, что произойдет, когда я выполню этот запрос

Я использую (читай обучение) ninject и у меня следующий код

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

   //some functions

}

У меня есть следующий класс "Product", который реализует интерфейс IProducts

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;
            }
        }
    }
}

Теперь я добавил

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

Интересно, что произойдет, если я добавлю еще один запрос Linq, такой как where product.Name == Something

Например

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;
     }
}

Насколько я знаю, запрос Linq будет выполняться только при циклическом переносе данных, поэтому мне интересно, объединятся ли эти два запроса Linq в один.

Например

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

Может ли кто-нибудь подтвердить меня, если я правильно понял

1 Ответ

2 голосов
/ 15 октября 2011

Компилятор эффективно преобразует ваши декларативные операторы LINQ в вызовы методов.(Я говорю эффективно , потому что на самом деле все зависит от того, происходит ли трансляция метода на самом деле или же он «сокращен» прямо в IL - нам не важно знать в этом контексте.)

То есть: -

from p in db.Products
    select p;

представляет

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

и

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

представляет

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

Теперь свыполнение откладывается , когда мы перечисляем наше окончательное значение («цикл по данным»), будет эффективно выполнено следующее: -

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

Затем до конкретной реализации IQueryable<T>(db.Products), чтобы перевести это на то, что подходит.В случае провайдера Linq2SQL это будет что-то вроде: -

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

Итак, вы видите, что из-за отложенного выполнения перевод для одного запроса к базе данных выполняется для вас.Вам не нужно предпринимать никаких специальных действий, чтобы это произошло.

...