Col*_*lin 33 c# extension-methods entity-framework
我是EF的新手,我正在尝试使用从我的数据库类型转换User为我的信息类的扩展方法UserInfo.
如果这有所作为,我首先使用数据库?
我的代码给出了错误
由于已经处理了DbContext,因此无法完成操作.
try
{
IQueryable<User> users;
using (var dataContext = new dataContext())
{
users = dataContext.Users
.Where(x => x.AccountID == accountId && x.IsAdmin == false);
if(users.Any() == false)
{
return null;
}
}
return users.Select(x => x.ToInfo()).ToList(); // this line is the problem
}
catch (Exception ex)
{
//...
}
Run Code Online (Sandbox Code Playgroud)
我可以看到为什么它会这样做,但我也不明白为什么where语句的结果没有被保存到users对象中?
所以我想我的主要问题是为什么它不起作用,其次是什么是使用扩展方法和EF的正确方法?
Jof*_*yHS 34
这个问题和答案让我相信IQueryable需要一个活跃的上下文来进行操作.这意味着你应该尝试这样做:
try
{
IQueryable<User> users;
using (var dataContext = new dataContext())
{
users = dataContext.Users.Where(x => x.AccountID == accountId && x.IsAdmin == false);
if(users.Any() == false)
{
return null;
}
else
{
return users.Select(x => x.ToInfo()).ToList(); // this line is the problem
}
}
}
catch (Exception ex)
{
...
}
Run Code Online (Sandbox Code Playgroud)
Ste*_* Py 26
在迭代或以其他方式访问它们之前暴露为实际IQueryable<T>并且IEnumerable<T>实际上不"执行"的对象,例如被组成一个List<T>.当EF返回IQueryable<T>它时,它本质上只是组成能够检索数据的东西,它实际上并不是在你使用它之前执行检索.
您可以通过在IQueryable定义的位置放置断点.ToList()来调用它,而不是在调用时.(正如Jofry正确指出的那样,从数据上下文的范围内.)在ToList()调用期间完成了拉取数据的工作.
因此,您需要保持IQueryable<T>在数据上下文的范围内.
Joe*_*ger 14
您需要记住,在枚举之前,IQueryable查询实际上并未针对数据存储执行.
using (var dataContext = new dataContext())
{
Run Code Online (Sandbox Code Playgroud)
除了构建SQL语句之外,这行代码实际上并没有做任何事情
users = dataContext.Users.Where(x => x.AccountID == accountId && x.IsAdmin == false);
Run Code Online (Sandbox Code Playgroud)
.Any()是一个枚举IQueryable的操作,因此SQL被发送到数据源(通过dataContext),然后对它执行.Any()操作
if(users.Any() == false)
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
你的"问题"一行是重用上面构建的sql,然后做一个额外的操作(.Select()),它只是添加到查询中.如果你把它留在这里,没有例外,除了你的问题
return users.Select(x => x.ToInfo()).ToList(); // this line is the problem
Run Code Online (Sandbox Code Playgroud)
调用.ToList(),它枚举IQueryable,这会导致SQL通过原始LINQ查询中使用的dataContext发送到数据源.由于此dataContext已被释放,因此它不再有效,并且.ToList()会抛出异常.
这就是"为什么它不起作用".修复是将这行代码移到dataContext的范围内.
如何正确使用它是另一个问题,有一些可以说是正确的答案取决于你的应用程序(Forms vs. ASP.net vs. MVC等).这实现的模式是工作单元模式.创建新的上下文对象几乎没有任何成本,因此一般规则是创建一个,完成工作,然后处理它.在Web应用程序中,有些人会根据请求创建一个Context.
| 归档时间: |
|
| 查看次数: |
95493 次 |
| 最近记录: |