我正在建模数据库以插入电影和电影。在影院上映。我知道剧院有很多会议,会议有电影和剧院。
public class Movie
{
public int MovieID { get; set; }
public String MovieName { get; set; }
public int Duration { get; set; }
public int Rate { get; set; }
}
public class Theater
{
public int TheaterID { get; set; }
public String TheaterName { get; set; }
public virtual ICollection<Session> Sessions { get; set; }
}
public class Session
{
public int SessionID { get; set; }
public int MovieID { get; set; }
public int TheaterID { get; set; }
public virtual Movie Movie { get; set; }
public virtual Theater Theater { get; set; }
}
我有一个接收一组会话的视图。在这个视图中,我使用foreach来显示剧院名称和所有电影:
这是来自控制器的代码:
public ActionResult MoviesSessions(int id)
{
Theater theater = db.Theater.Find(id);
ViewBag.TheaterName = Theater.TheaterName;
var sessions = from s in db.Sessions where s.TheaterID == id orderby s.MovieID select s;
return View(sessions);
}
这是在视图中:
@{
string theaterName = "";
foreach (var item in Model)
{
if (theaterName != item.Theater.TheaterName)
{
theaterName = item.Theater.TheaterName;
<tr>
<td>@Html.DisplayFor(modelItem => item.Movie.MovieName)</td>
</tr>
}
}
}
因为我使用item.Movie.MovieName
我收到以下错误:
&#34;已经有一个与此命令关联的开放DataReader,必须先关闭它。&#34;
是否已在控制器查询中填充Movie对象?我不明白为什么我会收到此错误。这是我第一次使用asp.net
答案 0 :(得分:1)
item.Movie属性是一个延迟查询,并尝试使用返回第一个查询结果的相同连接执行另一个数据库查询。某些数据库连接一次只允许一个活动的结果流,因此您必须首先读取所有行/实体,然后才能开始探索。您可以通过在查询(会话)上调用.ToList,然后将其传递给View函数来轻松完成此操作。此外,如果您使用的是SQL Server,则可以在连接字符串中设置“MultipleActiveResultSets = True”。
答案 1 :(得分:0)
您只需在连接字符串中设置MultipleActiveResultSets=true
即可。由于您正在循环查询,因此您正在读取第一个对象,然后您正在尝试加载item.Theater.TheaterName
,因为它具有导航属性并且它未包含在查询中,EF将触发第二个查询以加载{ {1}},因为之前的查询尚未完成,因为您的枚举未完成。如果MultipleActiveResultSet未设置为true,则会抛出错误。将其设置为true将允许EF在同一连接上打开多个打开的查询。
item.Theater.TheaterName
OR
其他方式是使用 connectionString="Data Source=MATT-PC\SQLEXPRESS;" +
"Initial Catalog=Raise;Integrated Security=True;" +
"MultipleActiveResultSets=true;"
或ToList
include
OR
// .ToList() will force entire query to load and close data reader
foreach(var m in Model.ToList()){
....
}
推荐
// since you are only interested in Theater, you could eager load
// Theater, this will cause EF to load Theater along with Movies in single
// query
foreach(var m in Model.Include("Theater")){
....
}
许多人认为这会导致代码中的双重枚举,但这也会减少sql server上的开放查询时间,这有助于减少事务死锁和超时。在底层,SQL查询对整个枚举是开放的,在事务中,它肯定会损害SQL的性能。