Многие ко многим с LINQ-To-Sql и ASP.NET MVC - PullRequest
2 голосов
/ 18 марта 2010

Я ограничу это тремя таблицами, которые я пытаюсь работать с Проблемой, Коммуникациями и ProbComms. Сценарий заключается в том, что у ученика может быть много проблем одновременно, которые могут повлиять на его учебу. Лекторы могут общаться со студентом в будущем после того, как начальная проблема зарегистрирована, однако, поскольку у студента может быть несколько проблем, лектор может решить, что их обсуждение связано с более чем одной проблемой.

Вот снимок экрана с представлением LINQ-To-Sql моей БД:

Снимок экрана LINQ-To-Sql

На данный момент в моем 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 работает нормально и возвращает экземпляр студента для вывода на странице, ниже студента я выводю все проблемы, зарегистрированные против них, но под этими проблемами я хочу показать сообщения, связанные с проблемой.

LINQ, который я использую для ProbComms, находится в классе 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

Запрос возвращает две строки, поэтому я предполагаю, что мне как-то нужно сгруппировать задачу или 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>

Проблема заключается в том, что при использовании данных примера перед тем, как Модель имеет две записи для одной и той же проблемы, поскольку существует две связи для этой проблемы, следовательно, дублируется вывод.

Буду признателен за любую помощь в этом.

Спасибо

Jon

1 Ответ

1 голос
/ 18 марта 2010

Я недавно много боролся со многими отношениями в 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 и отправлять их на просмотр.Они уже должны быть связаны.Только студент должен быть отправлен на просмотр.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...