开发者

Why I can’t find any benefit of caching LINQ to Entity query?

Please look at my sourcecode.

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

开发者_运维技巧I try to call Select method about 1000 times and call Select2 method about 1000 times. But the result shows me that Select2 method is a bit faster than Select method about 0.005 s.(0.052/0.057 s.) Moreover, this capture doesn't include time for creating EntityQuery object.

What's wrong with my source code?

PS. the following code show how to call methods.

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


In Select2() generated code is

SELECT TOP 1 * FROM ...

In Select() aggregating is done on top of request. Don't know for sure, but it could lead to .Compile() results being discarded.

Try to move .First() into the compiled query.

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();
);

Hope this will help.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜