MVC3 DbExtensions.Include Method Null Values



我有这两个数据库表,它们的模型如下:

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.Nullable 1[System.Int32],System.String,System.Nullable 1[System.DateTime],System.Nulleble 1[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)
    }
}

最新更新