Ø 简介
本文主要记录 EF(Entity Framework) 在平时的开发中可能遇到的异常,以及应该如何去解决。
1. System.InvalidOperationException
1) 异常描述:无法为具有固定名称“System.Data.SqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类型“System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer”。请确保使用限定程序集的名称且该程序集对运行的应用程序可用。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=260882。
2) 异常解释:这个异常有可能是因为我们运行程序目录中不存在 EntityFramework.SqlServer.dll,而 EF 对数据库的操作需要依赖该程序集,但是在我们引用的“数据访问层”类库中并没有使用到 EntityFramework.SqlServer.dll,所以并不会输出到运行程序目录。
3) 解决办法(2种方法):
1. 直接在运行程序项目中引用 EntityFramework.SqlServer.dll,但是这种方法比较繁琐,因为每个引用了“数据访问层”的运行项目中都必须这样去引用(比较麻烦或容易忘记)。
2. 【推荐】在“数据访问层”的项目中实现对 EntityFramework.SqlServer.dll 的直接依赖,这样每个引用了“数据访问层”的项目都会输出该程序集,例如在 EF 数据上下文中添加如下代码:
static MyTestingContext()
{
//使得 EntityFramework.SqlServer.dll 能够输出到运行程序目录中
if (typeof(System.Data.Entity.SqlServer.SqlFunctions) == typeof(object)) { }
}
2. System.Data.ProviderIncompatibleException 或 System.Data.Entity.Core.ProviderIncompatibleException
1) 异常描述:这个异常让我折腾了老半天,硬是下午都没找到原因!网上有人说是数据库连接配置有问题,但是这是公司项目数据库连接基本不变,怎么就有问题了!而且 EF 这块的代码也没怎么改,就莫名奇妙冒出这个异常了,记得当时有个异常信息:EF 提供程序未返回 ProviderManifestToken 字符串。
2) 解决办法:无论我各种改就是不行,后来尝试重启下 VS 后来居然可以了。所以总结下,当无法找到异常问题时,可以尝试重启 VS 或者电脑,搞不好是开发环境或开发工具出了问题。当然这个问题肯定还是某程序出问题了,可能重启 VS 刚好能解决这个问题吧。
3. System.NotSupportedException
1) 异常描述:LINQ to Entities 不支持 LINQ 表达式节点类型“ArrayLength”。这个异常可能是因为以下语法导致,举例:
int[] ccIds = RepositoryHelper.GetLastCateringCategoryIds(cateringTypeId, cateringCategorys);
var dataList = (from t1 in DataContext.CateringCategorys
where (ccIds.Length == 0 || ccIds.Contains(t1.CategoryId))
select t1).ToList();
2) 解决办法:这是因为在 LINQ to Entities 中不支持数组的 Length 属性,但是支持 List.Count 属性和方法,将集合 ccIds 改为 List<int> 类型即可。
4. 数据提交异常
1) 异常描述:
1. System.Data.Entity.Core.EntityException:An error occurred while starting a transaction on the provider connection. See the inner exception for details.
2. System.Data.SqlClient.SqlException:不允许启动新事务,因为有其他线程正在该会话中运行。
2) 解决办法:通常情况下可能是因为 dbContext.SaveChanges(); 代码再循环中执行导致,将该方法的调用放在循环外面即可。具体原因未知!