c# – 已经有一个必须先关闭的开放DataReader
|
在我的映射逻辑层(Model to ViewModel)中,我试图填充一个SelectListItem,以便在我的编辑视图中使用
HTML.DropDownListFor帮助器.
我尝试使用以下代码示例中的查询来检索品牌名称列表以填充SelectListItem,但触发了以下异常:
制图 public class MedicalProductMapper
{
private MvcMedicalStoreDb _db; // DataContext class
public MedicalProductMapper(MvcMedicalStoreDb db)
{
_db = db;
}
public MedicalProductViewModel GetMedicalProductViewModel(MedicalProduct source)
{
MedicalProductViewModel viewModel = new MedicalProductViewModel();
viewModel.ID = source.ID;
viewModel.Name = source.Name;
viewModel.Price = source.Price;
viewModel.BrandID = source.BrandID;
// This following line produces the exception
viewModel.BrandName = _db.Brands.Single(b => b.ID == source.BrandID).Name;
var queryBrands = from b in _db.Brands
select b;
viewModel.BrandSelectListItem = queryBrands as IEnumerable<SelectListItem>;
return viewModel;
}
}
我知道通过在连接字符串中启用多个活动结果集(MARS)可以轻松解决问题,但我想知道是否有办法在不修改连接字符串的情况下执行我想要的操作. 这里有一些更多的类,以防它们有助于解决这个问题: 编辑视图 @model MvcMedicalStore.Models.MedicalProductViewModel
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>MedicalProduct</legend>
@Html.HiddenFor(model => model.ID)
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Price)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Price)
@Html.ValidationMessageFor(model => model.Price)
</div>
// BRAND NAME
<div class="editor-label">
@Html.LabelFor(model => model.BrandName)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.BrandName,Model.BrandSelectListItem)
@Html.ValidationMessageFor(model => model.BrandName)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List","Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
控制器: public class MedicalProductController : Controller
{
private MvcMedicalStoreDb _db = new MvcMedicalStoreDb();
//
// GET: /MedicalSupply/
public ActionResult Index()
{
var viewModel = _db.Products.AsEnumerable()
.Select(product => GetMedicalProductViewModel(product));
return View(viewModel);
}
public MedicalProductViewModel GetMedicalProductViewModel(MedicalProduct product)
{
var mapper = new MedicalProductMapper(_db);
return mapper.GetMedicalProductViewModel(product);
}
public MedicalProduct GetMedicalProduct(MedicalProductViewModel viewModel)
{
var mapper = new MedicalProductMapper(_db);
return mapper.GetMedicalProduct(viewModel);
}
//
// GET: /MedicalSupply/Edit/5
public ActionResult Edit(int id = 0)
{
MedicalProduct medicalProduct = _db.Products.Find(id);
if (medicalProduct == null)
{
return HttpNotFound();
}
var viewModel = GetMedicalProductViewModel(medicalProduct);
return View(viewModel);
}
//
// POST: /MedicalSupply/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(MedicalProduct medicalProduct)
{
if (ModelState.IsValid)
{
_db.Entry(medicalProduct).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
var viewModel = GetMedicalProductViewModel(medicalProduct);
return View(viewModel);
}
}
堆栈跟踪
解决方法
您在每个产品的选择中提出另一个请求.但是您的产品被枚举,因此第一个datareader没有关闭.这就是您打开多个数据加载器的原因.
public ActionResult Index()
{
var products = _db.Products.ToArray() // force loading the results from database
// and close the datareader
var viewModel = products.Select(product => GetMedicalProductViewModel(product));
return View(viewModel);
}
附加:我认为您应该优化您的模型创建:您为数据库中的每个产品提出相同的请求(选择品牌). 为避免不必要的多个数据库往返,您应该: >加载您的产品>加载您的品牌>使用一个产品和从步骤2中获取的品牌来构建模型 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
