EF框架数据库操作的问题

王广大的烦恼 2018-09-07 09:28:54
List<landcom_admin_login_record_admin> DATA = new List<landcom_admin_login_record_admin>();
foreach (var admin1 in adminList)
{
//遍历所有的admin,获取每一个admin的登录信息
List<landcom_admin_login_record_admin> data = await admin.FindAdminLoginRecordAndAdminByadminId(admin1.id);
data = data == null ? new List<landcom_admin_login_record_admin>() : data;
DATA = DATA.Concat(data).ToList();
}
//该排序方法执行时间过久
DATA = DATA.OrderByDescending(a => a.landcom_admin_login_record.time).ToList();

想不通红色这句为什么会执行数据库操作,因为是自学。我的理解是不是只有存在DbContext的派生类对象才能操作数据库 还有个问题就是为什么这句执行的这么慢,我看vs中这句一直在查询。这不就是给集合根据集合中元素的某个值进行排序嘛,有点懵
...全文
519 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
王广大的烦恼 2018-09-10
  • 打赏
  • 举报
回复
礼拜五不好意思,因为下班比较早,没给您回复。不太礼貌 向您道个歉
王广大的烦恼 2018-09-10
  • 打赏
  • 举报
回复
adminList是List集合 也就是IEnumerable吧。 DATA = DATA.OrderByDescending(a => a.landcom_admin_login_record.time).ToList();

我把这句拆分了加断点 1 var dataed=DATA.OrderByDescending(a => a.landcom_admin_login_record.time);

2 DATA=dataed.ToList(); //这句是一直在查。 那天周五请教了一个老师,忘了给您回复 他说的这句是将IOrderedEnumerable 的dataed转换为List类型的DATA。因为1处的OrderByDescending中的是参数类型是个委托,所以到了第二句要转换集合的时候才会去数据库中查 。有461条登录记录,速度很慢他说数据库设计的不合理,EF框架用的也不好。请问一下现在开发.netMVC大部分使用的什么持久层框架,我也想不通为什么个EF框架为什么要在查出来的时候再重新排序,是因为没有原生的SQL吗,以前都是在sql中order by 这个框架是不是类似我之前学java时候学过的hibernate 是对数据库表 关系的映射。您能推荐个持久层框架让我学习下嘛
正怒月神 2018-09-10
  • 打赏
  • 举报
回复
ef就够了。
我建议,你使用sqlprofile查看一下,数据访问的sql把。
我估计是你当中某个地方,不断的在查找。
王广大的烦恼 2018-09-07
  • 打赏
  • 举报
回复
从网上看了IQueryable 和 IEnumerable

DATA.OrderByDescending(a => a.landcom_admin_login_record.time) 我F12进去 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

再F12进去
public interface IOrderedEnumerable<TElement> : IEnumerable<TElement>, IEnumerable 是不是可以这样认为 这个OrderByDescending方法返回值就是 IEnumerable接口。
OrderByDescending方法的参数是Func 通过您的建议看了后 摘录了https://blog.csdn.net/q646926099/article/details/52297897其中两点

1. Func<>谓词表达式,就是一个委托,委托一旦调用,就立即执行了,将执行结果保存在内存中。

2.Expression是一个表达式,会存储拼接表达式树,直到在运行期最终执行。
我有三个问题
1这个博主说的调用 执行 是不是OrderByDescending方法执行时 就已经去数据库执行了 还是其他的什么 那您说的ToList()是去执行操作的 我是不是理解错了请您帮忙给我解释下
昨天刚看懂了where 我跟您说说我的理解
var AdmidE=await db.landcom_admin.Where(a=>a.id.Equals(gr.userId)).SingleOrDefaultAsync();
红色处的DbSet调用扩展方法where F12进去
public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
2这个方法参数中Expression 就如我摘录的第二条所说的 他还请您帮忙解释下他这句话

3
DATA = DATA.OrderByDescending(a => a.landcom_admin_login_record.time).ToList();

我断点调试过 DATA已经是一个集合了 ,为什么排序的时候还要去数据库查 我想不通 有没有其他的方法
正怒月神 2018-09-07
  • 打赏
  • 举报
回复
ToList() 会去执行操作。
这个你需要了解
IQueryable 和 IEnumerable
举个例子
如果使用 DATA.OrderByDescending(a => a.landcom_admin_login_record.time)
那么生成的是一个IQueryable,这个时候你可以当做是一个sql语句,还没执行而已。
当你调用比如使用tolist,take,find,firstordefault等等方法时,
那么就变成了IEnumerable,他是会去数据库拉取数据的。
所以DATA.OrderByDescending(a => a.landcom_admin_login_record.time).ToList();会把前面一段生成的sql语句,通过tolist执行,到数据库拉去数据。
正怒月神 2018-09-07
  • 打赏
  • 举报
回复
引用 5 楼 qq_39938873 的回复:

看你的 adminList 是怎么获取的。
会不会是Iquerable类型的额?
如果是这样的话,会导致foreach中每次循环adminList 都会去数据库查询一遍。
如果是IEnumerable类型,那么foreach中的admin.FindAdminLoginRecordAndAdminByadminId(admin1.id);应该就不至于这么慢了。
不过具体还要看FindAdminLoginRecordAndAdminByadminId到底干了什么事。
这个分析起来,只能代码慢慢看了。
王广大的烦恼 2018-09-07
  • 打赏
  • 举报
回复
不好意思一直打扰您。谢谢百忙之中能回答我的问题,我加断点调试发现执行到这句的截图还请您看下 我想不通的是这都已经查出来了,这提示一直执行sql 就这这句要卡10秒左右。因为这是别人写的代码,我之前是学java的。对这些方法不太了解
王广大的烦恼 2018-09-07
  • 打赏
  • 举报
回复
正怒月神 2018-09-07
  • 打赏
  • 举报
回复
引用 2 楼 qq_39938873 的回复:
从网上看了IQueryable 和 IEnumerable

DATA.OrderByDescending(a => a.landcom_admin_login_record.time) 我F12进去 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

再F12进去
public interface IOrderedEnumerable<TElement> : IEnumerable<TElement>, IEnumerable 是不是可以这样认为 这个OrderByDescending方法返回值就是 IEnumerable接口。
OrderByDescending方法的参数是Func 通过您的建议看了后 摘录了https://blog.csdn.net/q646926099/article/details/52297897其中两点

1. Func<>谓词表达式,就是一个委托,委托一旦调用,就立即执行了,将执行结果保存在内存中。

2.Expression是一个表达式,会存储拼接表达式树,直到在运行期最终执行。
我有三个问题
1这个博主说的调用 执行 是不是OrderByDescending方法执行时 就已经去数据库执行了 还是其他的什么 那您说的ToList()是去执行操作的 我是不是理解错了请您帮忙给我解释下
昨天刚看懂了where 我跟您说说我的理解
var AdmidE=await db.landcom_admin.Where(a=>a.id.Equals(gr.userId)).SingleOrDefaultAsync();
红色处的DbSet调用扩展方法where F12进去
public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
2这个方法参数中Expression 就如我摘录的第二条所说的 他还请您帮忙解释下他这句话

3
DATA = DATA.OrderByDescending(a => a.landcom_admin_login_record.time).ToList();

我断点调试过 DATA已经是一个集合了 ,为什么排序的时候还要去数据库查 我想不通 有没有其他的方法

之前没有细看代码,我看了你上面的代码,和你在解释一下
1:
其实你要看前面的代码:
List<landcom_admin_login_record_admin> data = await admin.FindAdminLoginRecordAndAdminByadminId(admin1.id);
data = data == null ? new List<landcom_admin_login_record_admin>() : data;
DATA = DATA.Concat(data).ToList();
这里很明显FindAdminLoginRecordAndAdminByadminId 会抓取数据。因此已经不是Iquerable了。
那么后面的DATA.OrderByDescending(a => a.landcom_admin_login_record.time).ToList();其实已经是在内存里操作了。因为数据已经在前面抓出来了。

2 Expression 是一个表达式树,你就当做是一个拆分了的sql语句好了。传入表达式树,作为where条件,并不会抓取数据,
你的代码,是在admin.FindAdminLoginRecordAndAdminByadminId(admin1.id)就抓取了数据。
where条件单纯是不会抓取数据的。还是通过了SingleOrDefaultAsync去异步获取了。这就是我之前说的抓取数据,基本就是tolist,take,find......这些,当然也包括你的SingleOrDefault
至于你说的博客里,使用Expression还是Func<>这个很好辨别。
当数据是Iqueryable<>时,使用expression。
当数据是IEnumerable<>时,使用Func。
因为Iqueryable是一个sql语句,他还没办法调用具体额方法,所以需要表达式树这种类似于sql条件,来组装where
而IEnumerable<>时,已经将数据保存到内存里了,这个时候通过Func可以具体调用方法来操作数据。
3
在问题1上已经回答了。因为你的DATA来自于admin.FindAdminLoginRecordAndAdminByadminId(admin1.id);
这个时候数据已经在本地内存了。之后的DATA.OrderByDescending(a => a.landcom_admin_login_record.time).ToList();
其实只是在内存操作,并不访问数据库了。

8,497

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 LINQ
社区管理员
  • LINQ
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧