0

我正在重写这个问题:

我有2个模型。条目和主题。

public class Entry
{
    public int EntryId { get; set; }
    public int UserId { get; set; }
    public int TopicId { get; set; }

    public String EntryQuestion { get; set; }
    public String EntryAnswer { get; set; }
    public int EntryReview { get; set; }
    public String QuestionValidationURL { get; set; }

    public virtual ICollection<Topic> TopicList { get; set; }
}

public class Topic
{
    public int TopicId { get; set; }
    public String TopicName { get; set; }
}

我按照 ASP.Net/MVC 上的示例以这种方式设置我的模型。我想做的是对于每个条目项我都有一个 TopicId,但是我想通过访问我的 TopicList 将其转换为 TopicName。

我的问题是,如何加载 TopicList?

在我遵循的示例中,我看到了一些关于 LazyLoading 和 EagerLoading 的信息,但它似乎不起作用。

我尝试从我的入口控制器执行以下操作:

    db.Entries.Include(x => x.TopicList).Load();

但这仍然给了我一个 0 的 TopicList(这比 null 好)

我怎样才能做到这一点?

在我看来,我绑定到这样的条目:

@model IEnumerable<projectInterview.Models.Entry>

我想在这里访问主题列表:

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.TopicId)
        </td>
        ...
    </tr>

我想在这个循环中使用 TopicId 并显示作为集合中对象一部分的 TopicName。

4

5 回答 5

3

我假设您正在关注实体框架示例。据我所知,您正在尝试建立一对多的关系,尽管我不确定哪一端是哪一端。

在一般情况下,要建立一对多关系,您必须执行以下操作:

public class One
{
    [Key]
    public int Id { get; set; }

    public virtual ICollection<Many> Many { get; set; }
}

public class Many
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("One")]
    public int OneId { get; set; }
    public virtual One One { get; set; }
}

如果你想做的是让一个Entry与许多Topic对象相关,那么你就快到了,但你缺少一些东西。

为了ICollection<Topic>真正包含任何东西,(许多)Topic对象需要有一个指向 (one) 的外键Entry。(在两边显式标记主键也没有什么坏处,而不是依赖 EF 约定。)

public class Topic
{
    [Key]
    public int TopicId { get; set; }
    public String TopicName { get; set; }

    [ForeignKey("Entry")]
    public int EntryId { get; set; }
    public virtual Entry Entry { get; set; }
}

public class Entry
{
    [Key]
    public int EntryId { get; set; }

    public int UserId { get; set; }
    public int TopicId { get; set; }

    public String EntryQuestion { get; set; }
    public String EntryAnswer { get; set; }
    public int EntryReview { get; set; }
    public String QuestionValidationURL { get; set; }

    public virtual ICollection<Topic> TopicList { get; set; }
}

现在TopicList应该是一个实际且填充的集合,无需执行Include.


另一方面,如果你想要一个Topic与许多Entry对象相关的东西,那么你就有点倒退了。正确的方法是:

public class Topic
{
    [Key]
    public int TopicId { get; set; }

    public String TopicName { get; set; }

    public virtual ICollection <Entry> Entries { get; set; }
}

public class Entry
{
    [Key]
    public int EntryId { get; set; }

    public int UserId { get; set; }

    public String EntryQuestion { get; set; }
    public String EntryAnswer { get; set; }
    public int EntryReview { get; set; }
    public String QuestionValidationURL { get; set; }

    [ForeignKey("Topic")]
    public int TopicId { get; set; }
    public virtual Topic Topic { get; set; }
}

在这种情况下,您可能会使用也可能不会使用db.Entries.Include(x => x.Topic),具体取决于您是希望它们一次全部加载还是按需一个一个加载。无论您选择什么,以下表达式都应返回正确的值:

myEntry.Topic.TopicName
于 2013-08-08T13:44:38.853 回答
1

如果我理解正确,您已将主题列表添加到条目中,只是为了在显示条目时获取主题名称。最好的方法是在你的入口模型中实际拥有一个 Topic 属性。所以你的模型看起来像这样:

public class Entry
{
    public int EntryId { get; set; }
    public int UserId { get; set; }
    public int TopicId { get; set; }
    public String EntryQuestion { get; set; }
    public String EntryAnswer { get; set; }
    public int EntryReview { get; set; }
    public String QuestionValidationURL { get; set; }
    //Change this.....
    public virtual Topic Topic { get; set; }
}

然后在您看来,您将使用(假设模型是 IEnumerable):

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => modelItem.Topic.TopicName )
    </td>
    ...
</tr>

这个链接有一个很好的例子来说明如何做到这一点: http ://weblogs.asp.net/manavi/archive/2011/03/28/associations-in-ef-4-1-code-first-part-2-复杂类型.aspx

于 2013-08-08T14:24:19.907 回答
0

在我看来,问题在于铸造。在视图中你有IEnumerable<projectInterview.Models.Entry>while Topicsis ICollection<Topic>,它是不同类型的集合

于 2013-08-06T04:09:11.450 回答
0

似乎您没有Topics在代码中的任何位置初始化。如果集合为空,则表示它未初始化。如果你用它实例化它

ICollection<Topic> Topics = new List<Topic>();

初始化后,您应该在调用时收到零Topics.Count。如果您不调用数据库,它将保持为零。

在您的情况下,检查您是否正在实例化Topics.

于 2013-08-06T06:50:37.880 回答
0

Topics = null 表示列表中没有要迭代的主题。你如何填充它们?您的视图期望 IEnumerable 您如何将主题投射到条目中?

基于原始问题,我添加了一个小的工作示例,也许它可以帮助您找到错误。

控制器:

public class TestController : Controller
{
    public ActionResult Index()
    {
        var viewModel = new ViewModel()
        {
            Topics = new List<Topic>()
        };

        viewModel.Topics.Add(new Topic() { header = "test" });
        viewModel.Topics.Add(new Topic() { header = "test2" });

        return View(viewModel);
    }

}

模型:

public class ViewModel
{
    public virtual ICollection<Topic> Topics { get; set; }

    public int getCount()
    {
        return Topics.Count;
    }
}

public class Topic
{
    public string header { get; set; }
}

看法:

@model testProject.Models.ViewModel
@{
   ViewBag.Title = "Index";
}

<h2>Index</h2>
@Model.getCount()

@foreach(var item in Model.Topics)
{
    <div>@item.header</div>
}

输出:

索引 2 测试 test2

于 2013-08-06T06:00:58.800 回答