MVC3 DbExtensions.Include方法空值

时间:2012-03-26 16:01:04

标签: asp.net asp.net-mvc-3

我有这两个数据库表,模仿如下:

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>

我的问题是item.CalloutTypeValues对象为NULL,因此我的视图中没有填充值和注释。

谁能告诉我我做错了什么?

我已经用Google搜索了一下,并且提到我需要使用虚拟关键字明确加载这些实体,但我相信我在实体类中做了什么

增加:

我使用LINQ to 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));
}

但是我的视图中有不正确的模型,所以我收到了这个错误:

  

传递到字典中的模型项是类型的   &#39; {System.Data.Entity.Infrastructure.DbQuery {1}} 9 [System.Int32,System.Int32,System.Nullable 1[<>f__AnonymousType1 1的System.DateTime],System.Nullable {{1} } 1 [System.Int32],System.String,System.String]]&#39 ;,   但是这个字典需要一个类型的模型项   &#39; System.Collections.Generic.IEnumerable`1 [MarketingWebsiteTools.Models.CalloutToProduct]&#39;

提前致谢。

道格

1 个答案:

答案 0 :(得分:0)

看起来你的视图

@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)
    }
}