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 use
AsNoTracking()
data from the inner tables (table2,3) is lost during the conversion at this linevar 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?
First of all, it does not make sense to use
db.Configuration.ProxyCreationEnabled = false
andAsNoTracking()
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 guess it's good for performance reason. If turn it on, you will get expected result, but Entity Framework will make additional 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)
.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.
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}),
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
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.