我有这两个数据库表,它们的模型如下:
CalloutToProduct
-----------------
| id
| CalloutID
| CalloutTypeID
| ProductIdentifier
| DateStart
| DateEnd
| IsActive
-----------------
CalloutTypeValue
-----------------
| id
| CalloutTypeID
| Value
| Comment
-----------------
(顺便说一句,数据库似乎建模得很差,这些表与大多数(如果不是所有的话)数据库一样,都没有标准化,也没有与这些表上设置的适当PK或FK建立适当的关系,所以在所有条件相同的情况下,我认为关系是1比1。
作为MVC的新手,我不确定这是否是我问题的一部分…)
继续,我还以代码优先的方式创建了这两个类模型:
public class CalloutToProduct
{
[Key, ForeignKey("CalloutTypeValues")]
public int id { get; set; }
public int CalloutID { get; set; }
public int? CalloutTypeID { get; set; }
public string ProductIdentifier { get; set; }
public DateTime? DateStart { get; set; }
public DateTime? DateEnd { get; set; }
public int? IsActive { get; set; }
public virtual CalloutTypeValue CalloutTypeValues { get; set; }
}
public class CalloutTypeValue
{
[Key, ForeignKey("CalloutToProduct")]
public int id { get; set; }
public int? CalloutTypeID { get; set; }
public string Value { get; set; }
public string Comment { get; set; }
public virtual CalloutToProduct CalloutToProduct { get; set; }
}
And a context model:
public class CalloutToProduct
public class CalloutContext : DbContext
{
public DbSet<CalloutToProduct> CalloutToProduct { get; set; }
public DbSet<CalloutTypeValue> CalloutTypeValue { get; set; }
public DbSet<CalloutValue> CalloutValue { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
我还有一个使用DbExtensions的控制器。Include方法设置如下:
public ViewResult Index(int page = 1)
{
var callouts = db.CalloutToProduct.Include(c => c.CalloutTypeValues);
return View(callouts
.OrderBy(p => p.DateStart)
.Skip((page - 1) * PageSize)
.Take(PageSize));
}
一个看起来像这样的视图:
@model IEnumerable<MarketingWebsiteTools.Models.CalloutToProduct>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
CalloutID
</th>
<th>
CalloutTypeID
</th>
<th>
ProductIdentifier
</th>
<th>
@Html.ActionLink("Date Start", "Index", new { SortOrder=ViewBag.NameSortParm })
</th>
<th>
DateEnd
</th>
<th>
IsActive
</th>
<th>Value</th>
<th>Comments</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.CalloutID)
</td>
<td>
@Html.DisplayFor(modelItem => item.CalloutTypeID)
</td>
<td>
@Html.DisplayFor(modelItem => item.ProductIdentifier)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateStart)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateEnd)
</td>
<td>
@Html.DisplayFor(modelItem => item.IsActive)
</td>
<td>
@Html.DisplayFor(modelItem => item.CalloutTypeValues.Value)
</td>
<td>
@Html.DisplayFor(modelItem => item.CalloutTypeValues.Comment)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.id }) |
@Html.ActionLink("Details", "Details", new { id=item.id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.id })
</td>
</tr>
}
</table>
我的问题是这个项目。CalloutTypeValues对象为NULL,因此在我的视图中不会填充Value和Comment。
有人能告诉我我做错了什么吗?
我在谷歌上搜索了一下,上面提到我需要使用virtual关键字显式加载这些实体,但我相信这就是我在Entity类中所做的。
添加:
我使用LINQ将控制器更改为SQL,如下所示:
public ViewResult Index(int page = 1){
var callouts = from c in db.CalloutToProduct
join ctv in db.CalloutTypeValue on c.CalloutTypeID equals ctv.CalloutTypeID
select new
{
c.id,
c.CalloutID,
c.CalloutTypeID,
c.ProductIdentifier,
c.DateStart,
c.DateEnd,
c.IsActive,
ctv.Value,
ctv.Comment
};
return View(callouts
.OrderBy(p => p.DateStart)
.Skip((page - 1) * PageSize)
.Take(PageSize));
}
但我认为模型不正确,所以我收到了这个错误:
传递到字典中的模型项的类型为"System.Data.Entity.Infrastructure.DbQuery
1[<>f__AnonymousType1
9[System.Int32,System.Int32,System.Nullable1[System.Int32],System.String,System.Nullable
1[System.DateTime],System.Nulleble1[System.DateTime],System.Nullable
1[System.It32],System.String,System.String]]",但是这本字典需要类型为的模型项'System.Collections.Generic.IEnumerable`1[MarketingWebsiteTools.Models.CalloutToProduct]'.
提前谢谢。
Doug
看起来您的视图有
@model IEnumerable<MarketingWebsiteTools.Models.CalloutToProduct>
并且您正在向其传递匿名类型。请尝试创建一个名为CalloutToProductViewModel
的ViewModel,并将您的查询项映射到ViewModel
旁注:保持你的控制器精简,并将你的业务投入到服务中
查看
@model IEnumerable<MarketingWebsiteTools.Models.CalloutToProductViewModel>
控制器
public ViewResult Index(int page = 1){
var model = CalloutService.GetCallouts(page);
return View(model);
}
服务
public class CalloutService
{
public CalloutToProductViewModel GetCallouts(int page)
{
var callouts = from c in db.CalloutToProduct
join ctv in db.CalloutTypeValue on c.CalloutTypeID equals ctv.CalloutTypeID
select new
{
c.id,
c.CalloutID,
c.CalloutTypeID,
c.ProductIdentifier,
c.DateStart,
c.DateEnd,
c.IsActive,
ctv.Value,
ctv.Comment
};
// ******
var calloutVM = // map the anonymous type to a POCO View Model and do your orders
// ******
// .OrderBy(p => p.DateStart)
// .Skip((page - 1) * PageSize)
// .Take(PageSize));
return (calloutsVM)
}
}