在下面的剪辑中,我尝试使用Anonymous Projection
获取数据,我希望不跟踪所提取的entities
。
注意:我已经解决了现有的堆栈问题,但无法为我找到有效的解决方案
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();
}
当我使用内部表格中的
AsNoTracking()
数据(表格2,3)时,在此行的转换过程中会丢失var result = myprojection.Select(g =>g.table1).FirstOrDefault();
修改
如果我删除
AsNoTracking()
,一切正常。
1)如何正确使用实体框架中的projection
和AsNoTracking
?
2)是否有其他选项可以删除此查询的跟踪?
有没有可行的解决方法?
答案 0 :(得分:1)
首先,使用起来没有意义
db.Configuration.ProxyCreationEnabled = false
和AsNoTracking()
在同一时间。
如果您使用db.Configuration.ProxyCreationEnabled = false
更改跟踪将关闭所有查询。
但是内部表2和3的问题不是由AsNoTracking()
引起的。
db.Configuration.LazyLoadingEnabled = false;
db.Configuration.ProxyCreationEnabled = false;
关闭延迟加载,我认为这对性能原因有好处。如果打开它,您将获得预期的结果,但实体框架将为 myprojection 结果中的每一行向Data Base进行额外的SQL查询。您应该更好地执行以下操作:
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();
}
在您的查询中使用
.Include(x=>x.Table2).Include(x=>x.Table3)
即可 强制实体Framerwork加载相关的Table2和Table3 查询数据库。
答案 1 :(得分:1)
使用ToList()
作为导航属性。请注意,它仍将在数据库中生成。 (的 EF6 强>)
// ..
table2 = x.Table2.Where(g => Some Condition).ToList(),
更新
使用 EF4 ,您可能需要手动映射table2
:
table2 = x.Table2.Where(g => CONDITION).Select(x => new {Foo = x.Bar}),
答案 2 :(得分:0)
也许你可以尝试这样:
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();
}
注意:我不试试这个。只是一个想法,我希望这对你有帮助
答案 3 :(得分:0)
当我使用AsNoTracking()来自内部表(table2,3)的数据在此行的转换过程中丢失var result = myprojection.Select(g => g.table1).FirstOrDefault();
您选择Table1,进入匿名类型,您将无法访问table2或table3,尽管导航属性是他们不会映射的。当您选择匿名类型时,实体会失去关系,您需要选择第二和第三表,或者不要将其拉入匿名类型。
将你的小伙子直接放在桌子上,然后拨打电话
var myprojection = db.Table1.Join(db.Table2.Where(x => yourcondition),
t1 => t1.id, t2 => t2.t1id, (t1, t2) => t1 );
然后你必须为table3做另一个连接
但你最好只在两个查询中进行调用