使用LINQ-To-Sql和ASP.NET MVC的多对多

时间:2010-03-18 17:34:56

标签: asp.net-mvc linq-to-sql

我将此限制为我尝试使用问题,通信和ProbComms的三个表。情景是学生可能同时有许多问题,这可能会影响他们的学习。在记录初始问题后,讲师可能会与学生进行未来的沟通,但是由于学生可能有多个问题,讲师可能会认为他们的讨论与多个问题有关。

以下是我的数据库的LINQ-To-Sql表示的屏幕截图:

LINQ-To-Sql Screenshot

在我的StudentController中,我有一个StudentFormViewModel类:

    //
//ViewModel Class
public class StudentFormViewModel
{
    IProbCommRepository probCommRepository;

    // Properties
    public Student Student { get; private set; }
    public IEnumerable<ProbComm> ProbComm { get; private set; }

    //
    // Dependency Injection enabled constructors
    public StudentFormViewModel(Student student, IEnumerable<ProbComm> probComm)
        : this(new ProbCommRepository())
    {
        this.Student = student;
        this.ProbComm = probComm;
    }

    public StudentFormViewModel(IProbCommRepository pRepository)
    {
        probCommRepository = pRepository;
    }
}

当我进入学生详细信息页面时,会运行:

        public ActionResult Details(string id)
    {
        StudentFormViewModel viewdata = new StudentFormViewModel(studentRepository.GetStudent(id),
            probCommRepository.FindAllProblemComms(id));

        if (viewdata == null)
            return View("NotFound");
        else
            return View(viewdata);
    }

GetStudent工作正常并返回学生的实例以在页面上输出,在学生下面我输出针对他们记录的所有问题,但在这些问题下面我想显示与问题相关的通信。

我用于ProbComms的LINQ它位于Model类ProbCommRepository中,可通过IProbCommRepository接口访问:

        public IQueryable<ProbComm> FindAllProblemComms(string studentEmail)
    {
        return (from p in db.ProbComms
                where p.Problem.StudentEmail.Equals(studentEmail)
                orderby p.Problem.ProblemDateTime
                select p);
    }

但是,例如,如果我在ProbComms表中有这些数据:

ProblemID CommunicationID 1 1 1 2

查询返回两行所以我假设我不知何故必须groupby问题或ProblemID但是我不太确定如何用我构建的东西来做这个,因为返回类型必须是ProbComm用于查询,因为那是什么模型类位于。

当谈到视图时,Details.aspx调用两个部分视图,每个部分视图都传递相关的视图数据,StudentDetails工作正常:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"  Inherits="System.Web.Mvc.ViewPage<MitigatingCircumstances.Controllers.StudentFormViewModel>" %>
<% Html.RenderPartial("StudentDetails", this.ViewData.Model.Student); %>
<% Html.RenderPartial("StudentProblems", this.ViewData.Model.ProbComm); %>

StudentProblems使用foreach循环遍历模型中的记录,我正在尝试另一个foreach循环来输出通信详细信息:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<MitigatingCircumstances.Models.ProbComm>>" %>

<script type="text/javascript" language="javascript">
    $(document).ready(function() {
        $("DIV.ContainerPanel > DIV.collapsePanelHeader > DIV.ArrowExpand").toggle(
                function() {
                    $(this).parent().next("div.Content").show("slow");
                    $(this).attr("class", "ArrowClose");
                },
                function() {
                    $(this).parent().next("div.Content").hide("slow");
                    $(this).attr("class", "ArrowExpand");
                });

    });           
</script>
    <div class="studentProblems">    
    <% var i = 0;

       foreach (var item in Model) { %>
            <div id="ContainerPanel<%= i = i + 1 %>" class="ContainerPanel">
                <div id="header<%= i = i + 1 %>" class="collapsePanelHeader">
                    <div id="dvHeaderText<%= i = i + 1 %>" class="HeaderContent"><%= Html.Encode(String.Format("{0:dd/MM/yyyy}", item.Problem.ProblemDateTime))%></div>
                    <div id="dvArrow<%= i = i + 1 %>" class="ArrowExpand"></div>
                </div>
                <div id="dvContent<%= i = i + 1 %>" class="Content" style="display: none">
                    <p>
                        Type: <%= Html.Encode(item.Problem.CommunicationType.TypeName) %>
                    </p>
                    <p>
                        Problem Outline:  <%= Html.Encode(item.Problem.ProblemOutline)%>
                    </p>
                    <p>
                        Mitigating Circumstance Form: <%= Html.Encode(item.Problem.MCF)%>
                    </p>
                    <p>
                        Mitigating Circumstance Level: <%= Html.Encode(item.Problem.MitigatingCircumstanceLevel.MCLevel)%>
                    </p>
                    <p>
                        Absent From: <%= Html.Encode(String.Format("{0:g}", item.Problem.AbsentFrom))%>
                    </p>
                    <p>
                        Absent Until:  <%= Html.Encode(String.Format("{0:g}", item.Problem.AbsentUntil))%>
                    </p>
                    <p>
                        Requested Follow Up:  <%= Html.Encode(String.Format("{0:g}", item.Problem.RequestedFollowUp))%>
                    </p>

                    <p>Problem Communications</p>
                    <% foreach (var comm in Model) { %>                            
                            <p>
                            <% if (item.Problem.ProblemID == comm.ProblemID)
                               { %>
                                    <%= Html.Encode(comm.ProblemCommunication.CommunicationOutline)%>
                            <% } %>
                            </p>
                 <% } %>
                   </div>
            </div>
            <br />
    <% } %>
    </div>

问题是在模型之前使用示例数据有两个记录用于同一问题,因为该问题有两个通信,因此重复输出。

非常感谢任何帮助。

谢谢,

乔恩

1 个答案:

答案 0 :(得分:1)

我最近在MVC中与很多人建立了很多关系。我终于让我的工作了。我很乐意帮助你,但不能完全理解你的问题。

当你说查询返回2行时,我认为它应该是因为该问题有2个通信。如果要为学生返回问题,则无需查询ProbComms表,只需查询问题表。然后,如果要返回这些问题的通信,请查询ProbComms表。

对于循环,您需要循环遍历问题,然后在该循​​环内循环执行特定于该问题的通信。非常松散的东西:

foreach (var p in Model.Student.Problem)
{
     <%= Html.Encode(p.ProblemInfoField) %>
     ...
     foreach (var c in p.ProbComms)
     {
        <%= Html.Encode(c.Communications.CommunicationInfoField) %>
         ...
     }
}

您无需在控制器中选择ProbComms并将其发送到视图。它们应该已经联系起来。只有学生需要被发送到视图。