DBContext 应该全局定义还是每次都显式创建?
Should DBContext be globally defined or explicitly created every time?
我是一个 SQL 的人,他正在修补 Web API 和 Entity Framework 6,当我的代码是:
namespace DataAccessLayer.Controllers
{
public class CommonController : ApiController
{
[Route("CorrespondenceTypes")]
[HttpGet]
public IQueryable GetCorrespondenceTypes()
{
using (var coreDB = new coreEntities())
{
var correspondenceType = coreDB.tblCorrespondenceTypes.Select(cor => new { cor.CorrespondenceTypeName });
return correspondenceType;
}
}
}
}
但是,如果稍微更改一下我的代码并尝试这样做,它会起作用:
namespace DataAccessLayer.Controllers
{
public class CommonController : ApiController
{
readonly coreEntities coreDB = new coreEntities();
[Route("CorrespondenceTypes")]
[HttpGet]
public IQueryable GetCorrespondenceTypes()
{
var correspondenceType = coreDB.tblCorrespondenceTypes.Select(cor => new { cor.CorrespondenceTypeName });
return correspondenceType;
}
}
}
我的问题是为什么第二个有效而第一个无效?每次使用全局连接字符串或显式调用 DBContext 是更好的做法吗?
您收到错误消息是因为您返回的 IQueryable Entity framework 尚未为其执行查询,并且在需要执行该查询时已释放 DbContext。
记住Entity framework在初始化集合或任何不支持延迟执行的方法之前不会执行查询。访问 this link 以获取 Linq 延迟执行支持方法的列表。
why does the second one work but not the first?
在第一个代码片段中,您将返回一个 IQuerable 实例,该实例尚未执行 DbQuery,然后在它触发后在您的上下文中进行处理 (coreDB
)。因此,每当您的代码遍历集合后,它都会尝试触发 DbQuery 但发现上下文已被破坏,因此您会收到错误消息。
在第二种情况下,当您遍历集合时 coreDB
上下文必须处于活动状态,这样您就不会收到错误。
Is it better practice to have a global connection string or call DBContext explicitly each time?
此问题的答案取决于开发人员的品味或他自己的舒适度。您可以使用包含在 using 语句中的上下文,如下所示:
public IList GetCorrespondenceTypes()
{
using (var coreDB = new coreEntities())
{
var correspondenceType = coreDB.tblCorrespondenceTypes.Select(cor => new { cor.CorrespondenceTypeName });
return correspondenceType.ToList();
}
}
如上面的代码片段所示,如果您在返回之前使用 ToList
,它将在您的 coreDB
被销毁之前执行查询。在这种情况下,您必须确保返回了具体化的响应(即在执行 DbQuery 后返回的响应)。
注意:我注意到大多数人选择第二种方式。将上下文作为实例字段或 属性.
我是一个 SQL 的人,他正在修补 Web API 和 Entity Framework 6,当我的代码是:
namespace DataAccessLayer.Controllers
{
public class CommonController : ApiController
{
[Route("CorrespondenceTypes")]
[HttpGet]
public IQueryable GetCorrespondenceTypes()
{
using (var coreDB = new coreEntities())
{
var correspondenceType = coreDB.tblCorrespondenceTypes.Select(cor => new { cor.CorrespondenceTypeName });
return correspondenceType;
}
}
}
}
但是,如果稍微更改一下我的代码并尝试这样做,它会起作用:
namespace DataAccessLayer.Controllers
{
public class CommonController : ApiController
{
readonly coreEntities coreDB = new coreEntities();
[Route("CorrespondenceTypes")]
[HttpGet]
public IQueryable GetCorrespondenceTypes()
{
var correspondenceType = coreDB.tblCorrespondenceTypes.Select(cor => new { cor.CorrespondenceTypeName });
return correspondenceType;
}
}
}
我的问题是为什么第二个有效而第一个无效?每次使用全局连接字符串或显式调用 DBContext 是更好的做法吗?
您收到错误消息是因为您返回的 IQueryable Entity framework 尚未为其执行查询,并且在需要执行该查询时已释放 DbContext。
记住Entity framework在初始化集合或任何不支持延迟执行的方法之前不会执行查询。访问 this link 以获取 Linq 延迟执行支持方法的列表。
why does the second one work but not the first?
在第一个代码片段中,您将返回一个 IQuerable 实例,该实例尚未执行 DbQuery,然后在它触发后在您的上下文中进行处理 (coreDB
)。因此,每当您的代码遍历集合后,它都会尝试触发 DbQuery 但发现上下文已被破坏,因此您会收到错误消息。
在第二种情况下,当您遍历集合时 coreDB
上下文必须处于活动状态,这样您就不会收到错误。
Is it better practice to have a global connection string or call DBContext explicitly each time?
此问题的答案取决于开发人员的品味或他自己的舒适度。您可以使用包含在 using 语句中的上下文,如下所示:
public IList GetCorrespondenceTypes()
{
using (var coreDB = new coreEntities())
{
var correspondenceType = coreDB.tblCorrespondenceTypes.Select(cor => new { cor.CorrespondenceTypeName });
return correspondenceType.ToList();
}
}
如上面的代码片段所示,如果您在返回之前使用 ToList
,它将在您的 coreDB
被销毁之前执行查询。在这种情况下,您必须确保返回了具体化的响应(即在执行 DbQuery 后返回的响应)。
注意:我注意到大多数人选择第二种方式。将上下文作为实例字段或 属性.