实体框架 - 一对多 - 从两个表中选择

时间:2017-02-07 13:21:49

标签: c# entity-framework

在我的数据库中,我有"放置"和"图像"表。 "图像"有一个来自Place的外键,这意味着每个地方都可以有多个图像。

我选择这样的地方:

var query = (from x in DB.Places
  where x.CityId == CityId 
  select x).ToList();

当我想通过query.Images.toList();访问其图片时,我收到此错误:

  

ObjectContext实例已被释放,无法再使用   对于需要连接的操作。

我的选择查询应该如何通过一个选择查询来获取一个地方及其图像?

提前谢谢你 MA。

4 个答案:

答案 0 :(得分:4)

您可以使用预先加载:

var query = (from x in DB.Places
             where x.CityId == CityId 
             select x).Include(p => p.Images).ToList();

在这种情况下,方法语法看起来更好

var query = DB.Places.Where(p => p.CityId == CityId).Include(p => p.Images).ToList();

另一种选择 - 在获得图像之前不要处理DbContext。例如。如果您使用using语句,只需在using块内删除它或获取图像。但它将使用第二次数据库查询来加载图像。

进一步阅读:Eager LoadingLazy Loading

答案 1 :(得分:1)

有两个选项:

1)启用预先加载(不太好主意)

2)保持延迟加载和包含您想要的实体。

选项2:

var query = DB.Places.Include(z => z.Images).Where(x => x.CityId == CityId).ToList();

您获得的异常是因为LazyLoading对象启用了context。您正试图访问EF以外的物业,我猜它已经处理好了。

在Lazy Loading中第一次调用属性实际上是连接数据库并检索所需的数据。

有关详情,请点击以下链接:https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx

答案 2 :(得分:1)

第一点!

您通过Include查询仅接受字符串,这意味着您对EF有一个抽象,我认为您使用的是DynamicLibrary。

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

第二点!

实体不会通过访问它们自动加载,这意味着您只使用Eager加载而不是延迟加载! - >我不知道你有什么!

在您的情况下,您始终要在执行任何查询之前包含集合,否则您将始终获得一个空集合!

<强>修正

protected $middleware = [
    // ... Other middleware references
    \App\Http\Middleware\CharsetMiddleware::class,
];

第三点!

您已发布DbContext置位异常,这意味着您正在使用范围之外的DbContext

修复

只要您使用它就不要丢弃DbContext!

答案 3 :(得分:0)

如果您启用了延迟加载,则会自动获取所选位置的图像。 所以在你的情况下,

var query = (from x in DB.Places
where x.CityId == CityId 
select x).ToList();

因为你正在列出对象。在访问特定项目的内部细节之前,您必须选择特定项目。

 : query.FirstOrDefault().Images.ToList(); // only to get the images of the first record in the list. If that list has values.

如果您启用了预先加载,则必须使用.Include()函数在执行第一次tolist之前加载所需的表。 我建议你选择选项1.

相关问题