Почему я не могу найти какую-либо выгоду от кэширования запроса LINQ to Entity? - PullRequest
0 голосов
/ 12 октября 2009

Пожалуйста, посмотрите на мой исходный код.

public class EntityQuery
{
    public static Func<AdventureWork2008Container, IQueryable<SalesPerson>> selectQuery = CompiledQuery.Compile
    (
        (AdventureWork2008Container aw) =>
        (
            from s in aw.SalesPerson
            join e in aw.Employee on s.BusinessEntityID equals e.BusinessEntityID
            join p in aw.Person on s.BusinessEntityID equals p.BusinessEntityID
            join bea in aw.BusinessEntityAddress on s.BusinessEntityID equals bea.BusinessEntityID
            join a in aw.Address on bea.AddressID equals a.AddressID
            join sp in aw.StateProvince on a.StateProvince equals sp
            select s
        )
    );

    public decimal Select(AdventureWork2008Container aw)
    {
        SalesPerson result = selectQuery(aw).First();
        return result.SalesYTD;
    }

    public decimal Select2(AdventureWork2008Container aw)
    {            
        SalesPerson result =
        (
            from s in aw.SalesPerson
            join e in aw.Employee on s.BusinessEntityID equals e.BusinessEntityID
            join p in aw.Person on s.BusinessEntityID equals p.BusinessEntityID
            join bea in aw.BusinessEntityAddress on s.BusinessEntityID equals bea.BusinessEntityID
            join a in aw.Address on bea.AddressID equals a.AddressID
            join sp in aw.StateProvince on a.StateProvince equals sp
            select s
        ).First();

        return result.SalesYTD;
    }
}

Я пытаюсь вызвать метод Select около 1000 раз, а метод Select2 - около 1000 раз. Но результат показывает, что метод Select2 немного быстрее, чем метод Select, примерно на 0,005 с. (0,052 / 0,057 с.) Более того, этот захват не включает время для создания объекта EntityQuery.

Что не так с моим исходным кодом?

PS. следующий код показывает, как вызывать методы.

    private void button1_Click(object sender, EventArgs e)
    {
        using (AdventureWork2008Container aw = new AdventureWork2008Container())
        {
            EntityQuery eq = new EntityQuery();

            eq.Select(aw);
            long lastTime = DateTime.Now.Ticks;

            for (int i = 0; i < 1000; i++)
            {
                eq.Select(aw);
            }
            listBox1.Items.Add("Select 1 : " + ShowTime(lastTime));
        }

        GC.Collect();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        using (AdventureWork2008Container aw = new AdventureWork2008Container())
        {
            EntityQuery eq = new EntityQuery();

            eq.Select2(aw);
            long lastTime = DateTime.Now.Ticks;

            for (int i = 0; i < 1000; i++)
            {
                eq.Select2(aw);
            }
            listBox1.Items.Add("Select 2 : " + ShowTime(lastTime));
        }

        GC.Collect();
    }

1 Ответ

0 голосов
/ 12 октября 2009

В Select2 () сгенерированный код

SELECT TOP 1 * FROM ...

В Select () агрегирование выполняется поверх запроса. Не знаю наверняка, но это может привести к тому, что результаты .Compile () будут отброшены.

Попробуйте переместить .First () в скомпилированный запрос.

public static Func<AdventureWork2008Container, SalesPerson> selectQuery = CompiledQuery.Compile
(
    (AdventureWork2008Container aw) =>
    (
        from s in aw.SalesPerson
        join e in aw.Employee on s.BusinessEntityID equals e.BusinessEntityID
        join p in aw.Person on s.BusinessEntityID equals p.BusinessEntityID
        join bea in aw.BusinessEntityAddress on s.BusinessEntityID equals bea.BusinessEntityID
        join a in aw.Address on bea.AddressID equals a.AddressID
        join sp in aw.StateProvince on a.StateProvince equals sp
        select s
    ).First();
);

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...