BestPractice: Как правильно отобразить связь «многие ко многим» в представлении? - PullRequest
0 голосов
/ 24 февраля 2010

Я использую NHibernate и у меня есть много-много связей между Сотрудником и Командой.

Теперь я хочу отобразить всех сотрудников с именем своего члена команды.

Возможность 1:

  • с помощью AutoMapper и создания DTO, содержащего свойства Employee и имя команды (готово загрузить команду)
  • отображать DTO в представлении

Возможность 2:

  • создать новый объект с именем EmployeeTeam и отобразить его с помощью NHibernate / FluentNHibernate (этот объект действует как реляционная таблица между сотрудником и командой в базе данных)
  • загрузка TeamEmployee с помощью активной загрузки включает Employee и Team
  • показать сущность EmployeeTeam
  • использовать членов EmployeeTeam (EmployeeTeam.Employee.Name, EmployeeTeam.Team.Name)

Возможность 3:

  • как возможности 1 и 2
  • с использованием DTO для EmployeeTeam

Возможность 4:

  • использовать ICriteria API
  • использовать AliasToBeanResultTransformer (не использовал это)

Возможность 5:

  • используйте LINQ to NHibernate
  • Я думаю, что мне все еще будет нужен объект EmployeeTeam (который пока отсутствует в моей доменной модели)

Каков наилучший метод решения этой проблемы?

Любые другие предложения?

Ответы [ 3 ]

2 голосов
/ 24 февраля 2010

Это звучит как кошмар пользовательского интерфейса, но вы можете просто передать свой список сотрудников для просмотра. Затем создайте вложенный цикл, который проходит по командам внутри цикла, который проходит по сотрудникам. В Asp.Net MVC это будет выглядеть примерно так -

<table>
    <thead>
        <tr>
            <td>Employee</td>
            <td>Team</td>
        </tr>
    </thead>
    <% foreach(var employee in Model.Employees) { %>
        <% foreach (var team in employee.Teams) { %>
            <tr>
                <td><%=employee.Name %></td>
                <td><%=team.Name %></td>
            </tr>
        <% } %>
    <% } %>
</table>

Вы должны использовать ViewModel (DTO) в следующих случаях -

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

Я бы избежал второго варианта, поскольку он просто добавляет ненужную сложность (из того, что я могу сделать вывод из текущей предоставленной информации) в ваш домен: -)

Обновление

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

<table>
    <thead>
        <tr>
            <td>Employee</td>
            <td>Team</td>
        </tr>
    </thead>
    <% foreach(var employee in Model.Employees) { %>
        <tr>
            <% if (employee.Teams.Any()) { %>
                <td><%=employee.Name %></td>
                <td> - </td>
            <% } else { %>
                <% foreach (var team in employee.Teams) { %>
                    <td><%=employee.Name %></td>
                    <td><%=team.Name %></td>
                <% } %>
            <% } %>
        </tr>
    <% } %>
</table>

Очевидно, что чем больше подобных настроек пользовательского интерфейса, тем больше вероятность того, что вы захотите использовать ViewModel для очистки вашего View. Если вы обнаружите, что ваше представление начинает становиться нечитаемым из-за количества ссылок на встроенный код, то это, как правило, указывает на применимость ViewModel (DTO): -)

0 голосов
/ 24 февраля 2010

создайте вид dto с полями, которые вы хотите отобразить как свойства. используя automapper - сопоставьте свойства сущности с вашим новым dto:

Mapper.CreateMap<Obj1, NewObjDto>()
                .ForMember(dest => dest.Prop1, opt => opt.MapFrom(src => src.Obj1.Prop1));

другими словами - ваш взгляд не должен напоминать ваши доменные объекты.

ш: //

0 голосов
/ 24 февраля 2010

Это зависит от того, хотите ли вы строго использовать DTO, чтобы отделить свою бизнес-логику от логики представления (архитектурное решение). В таком случае я бы предпочел решение 1.

Если у вас есть поведение для такой сущности, как EmployeeTeam, или будет повторное использование (например, в отчете), то я бы предпочел решение 2.

...