简体   繁体   English

实体框架`AsNoTracking`不能与匿名投影一起使用

[英]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. 在下面的剪辑中我尝试使用Anonymous Projection获取数据,我想不跟踪获取的entities

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 line var result = myprojection.Select(g =>g.table1).FirstOrDefault(); 当我使用AsNoTracking()来自内部表(table2,3 AsNoTracking()数据在此行转换期间丢失var result = myprojection.Select(g =>g.table1).FirstOrDefault();

Edit 编辑

If i remove AsNoTracking() everything works fine. 如果我删除AsNoTracking()一切正常。

1) How to use projection and AsNoTracking in entity framework correctly ? 1)如何在实体框架中正确使用projectionAsNoTracking

2) Any other option to remove tracking of this query? 2)删除此查询的跟踪的任何其他选项?

Is there any possible workarounds? 有没有可能的解决方法?

First of all, it does not make sense to use db.Configuration.ProxyCreationEnabled = false and AsNoTracking() at the same time. 首先,同时使用db.Configuration.ProxyCreationEnabled = falseAsNoTracking()是没有意义的。

If you use db.Configuration.ProxyCreationEnabled = false change tracking will turn off for all queries. 如果使用db.Configuration.ProxyCreationEnabled = false将关闭所有查询的更改跟踪。

But your problem with inner tables 2 and 3 is not caused by AsNoTracking() . 但是你的内部表2和3的问题不是由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. 如果打开它,您将获得预期的结果,但实体框架将为myprojection结果中的每一行向Data Base进行额外的SQL查询。 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. 在查询中使用.Include(x=>x.Table2).Include(x=>x.Table3)将强制Entity Framerwork将一个查询的相关Table2和Table3加载到Data Base。

Use ToList() for your navigation properties. 使用ToList()作为导航属性。 Note that it will still projekt in the DB. 请注意,它仍将在数据库中生成。 ( EF6 ) EF6

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

Update: 更新:

With EF4 you probably need to map table2 manually: 使用EF4,您可能需要手动映射table2

 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(); 当我使用AsNoTracking()来自内部表(table2,3)的数据在此行转换期间丢失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. 您选择Table1,进入匿名类型,您将无法访问table2或table3,尽管导航属性是他们不会映射的。 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 然后你必须为table3做另一个连接

but your probably better just making the call in two queries 但你最好只在两个查询中进行调用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM