Eldho February 2016

Entity framework `AsNoTracking` is not working with anonymous projection

In the below snipped i try to fetch data using Anonymous Projection and i would like do not track the entities that is fetched.

Note : i have already gone through existing stack question,yet unable to find a working solution for me

using (var db = new Entities())
{
     db.Configuration.LazyLoadingEnabled = false;
     db.Configuration.ProxyCreationEnabled = false;

     var myprojection = db.Table1
                        .AsNoTracking()
                        .Include(gh=>gh.Table2) //Update
                        .Include(gh=>gh.Table3) //Update
                        .Select(x => new
                        {
                            table1= x,
                            table2= x.Table2.Where(g => Some Condition),

                            table3= x.Table3.Where(g=>Some Condition)
                        })
                        .ToList();

    var result = myprojection.Select(g =>g.table1).FirstOrDefault();

}

When i useAsNoTracking() data from the inner tables (table2,3) is lost during the conversion at this line var result = myprojection.Select(g =>g.table1).FirstOrDefault();

Edit

If i remove AsNoTracking() everything works fine.

1) How to use projection and AsNoTracking in entity framework correctly ?

2) Any other option to remove tracking of this query?

Is there any possible workarounds?

Answers


Alper Tunga Arslan February 2016

Maybe you can try like this:

using (var db = new Entities())
    {
         db.Configuration.LazyLoadingEnabled = false;
         db.Configuration.ProxyCreationEnabled = false;

         var myprojection = db.Table1 
                            //.AsNoTracking()  //remove.AsNoTracking() from here
                            .Select(x => new
                            {
                                table1= x,
                                table2= x.Table2.Where(g => Some Condition),
                                table3= x.Table3.Where(g=>Some Condition)
                            })
                            .AsNoTracking()//add .AsNoTracking() here
                            .ToList();    

        var result = myprojection.Select(g =>g.table1).FirstOrDefault();    
    }

NOTE: I dont try this. Just an idea, i hope this helps to you


Володин Андрей February 2016

First of all, it does not make sense to use db.Configuration.ProxyCreationEnabled = false and AsNoTracking() at the same time. If you use db.Configuration.ProxyCreationEnabled = false change tracking will turn off for all queries. But your problem with inner tables 2 and 3 is not caused by AsNoTracking(). db.Configuration.LazyLoadingEnabled = false; db.Configuration.ProxyCreationEnabled = false; turn off lazy loading and i gues it's good for performance reason. If turn it on, you will get expected result, but Entity Framerwork will make aditioanal SQL query to Data Base for every row in myprojection result. You should better do the following:

    using (var db = new Entities())
    {
        db.Configuration.LazyLoadingEnabled = false;
        db.Configuration.ProxyCreationEnabled = false;


        var myprojection = db.Table1
                    .Include(x=>x.Table2).Include(x=>x.Table3)
                    //.AsNoTracking()
                    .Select(x => new
                    {
                        table1= x,
                        table2= x.Table2.Where(g => Some Condition),

                        table3= x.Table3.Where(g=>Some Condition)
                    })

                    .ToList();

        var result = myprojection.Select(g =>g.table1).FirstOrDefault();

    }

Using .Include(x=>x.Table2).Include(x=>x.Table3) in your query will force Entity Framerwork to load related Table2 and Table3 for one query to Data Base.


tenbits February 2016

Use ToList() for your navigation properties. Note that it will still projekt in the DB. (EF6)

// ..
table2 = x.Table2.Where(g => Some Condition).ToList(),

Update:

With EF4 you probably need to map table2 manually:

 table2 = x.Table2.Where(g => CONDITION).Select(x => new {Foo = x.Bar}),


johnny 5 February 2016

When i useAsNoTracking() data from the inner tables (table2,3) is lost during the conversion at this line var result = myprojection.Select(g =>g.table1).FirstOrDefault();

Your selecting Table1, into an anonymous type you will not have access to table2 or table3 although the navigation properties are they they will not map. Entities loses it relationships when you select into anonymous type you need to select table two and three or don't pull it into an anonymous type.

Just put your wheres directly in the table one where and then make your call

 var myprojection = db.Table1.Join(db.Table2.Where(x => yourcondition), 
                                     t1 => t1.id, t2 => t2.t1id, (t1, t2) => t1 );

then you have to do another join for table3

but your probably better just making the call in two queries

Post Status

Asked in February 2016
Viewed 1,302 times
Voted 13
Answered 4 times

Search




Leave an answer