EF导航属性使用常见异常

6 篇文章 0 订阅
2 篇文章 0 订阅

一、异常 The ObjectContext instance has been disposed and can no longer be used for operations that require a connection

在这里插入图片描述
遇到这种问题的原因,是EF连接被释放了,然后操作导航属性【而导航属性又去读取数据库值】导致出现“连接已经释放的异常”解决办法如下

1.将导航属性改为“非延迟加载”
Person p;
using (var context = new MyDbContext())
{
    //Include(x=>x.Dogs) 设置 Dogs 这个导航属性是“非延迟加载”的,直接将数据JOIN起来全部在一个查询中返回
    p = context.Persons.Include(x => x.Dogs).First();
}
Console.WriteLine(string.Join(",", p.Dogs.Select(x => x.Name)));
2.将属性先在连接未释放前查询出来
Person p;
ICollection<Dog> Dogs;
using (var context = new MyDbContext())
{
    p = context.Persons.First();
    Dogs = p.Dogs;//在连接未关闭前先将导航属性查询出来
}

Console.WriteLine(string.Join(",", Dogs.Select(x => x.Name)));
//这样也可以使用了,导航属性“延迟加载”实现逻辑其实就是:
//在调用导航属性的get方法时:之前查询出值了?[返回之前查询的值]:[查询数据库值并存入之前查询值变量中]
Console.WriteLine(string.Join(",", p.Dogs.Select(x => x.Name)));

二、InvalidOperationException: 已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭。

在这里插入图片描述
遇到这个异常的原因是因为:ADO.NET里面默认不允许在一个连接中,在上一个DataReader未关闭前打开新的DataReader进行读取数据!出现两个DataReader的原因也是因为导航属性的延迟加载,导致在遍历的过程中向数据库发送了查询请求并读取查询的数据导致的,解决办法如下:

1.设置导航属性为“非延迟加载”
using (var context = new MyDbContext())
{
    //Include(x => x.Dogs) 设置 Dogs这个导航属性为非延迟加载的
    foreach (var person in context.Persons.Include(x => x.Dogs))
    {
        Console.WriteLine("姓名:{0},拥有的狗:{1}", person.Name,
            string.Join(",", person.Dogs.Select(x => x.Name)));
    }
}
2.先将主查询全部查询完毕后再进行遍历
using (var context = new MyDbContext())
{
    //ToList()是先将当前查询查询返回成List<Person>集合后再进行遍历处理
    //ToList()操作结束后就会关闭查询的DataReader对象
    //因为下面的操作是单线程的操作所以在加载导航属性时候也不会出现在上一个DataReader未关闭前就打开下一个DataReader的情况
    foreach (var person in context.Persons.ToList())
    {
        Console.WriteLine("姓名:{0},拥有的狗:{1}", person.Name,
            string.Join(",", person.Dogs.Select(x => x.Name)));
    }
}
3.设置连接类型为支持在一个连接下有多个同时运行的DataReader此操作只支持SqlServer 2005以后的版本

在这里插入图片描述

MultipleActiveResultSets=true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值