AutoMapper: сопоставьте ассоциацию многие-ко-многим с DTO (поддерживается ли сглаживание элементов коллекции?)

У меня много ассоциаций между командой и сотрудником.

public class Employee : Entity
{
    public virtual string LastName { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string EMail { get; set; }
    public virtual IList<LoanedItem> LoanedItems { get; private set; }
    public virtual ISet<Team> Teams { get; private set; }

    public Employee()
    {
        if (LoanedItems == null)
        {
            LoanedItems = new List<LoanedItem>();
        }

        if (Teams == null)
        {
            Teams = new HashedSet<Team>();
        }
    }

    public virtual Employee AddTeam(Team team)
    {
        Teams.Add(team);
        team.Employees.Add(this);

        return this;
    }

    public virtual Employee RemoveTeamFromEmployee(Team team)
    {
        Teams.Remove(team);
        team.Employees.Remove(this);

        return this;
    }
}

public class Team : Entity
{
    public virtual string Name { get; set; }
    public virtual ISet<Employee> Employees { get; private set; }

    public Team()
    {
        if (Employees == null)
        {
            Employees = new HashedSet<Employee>();
        }
    }

    public virtual Team RemoveEmployeeFromTeam (Employee employee)
    {
        Employees.Remove(employee);
        employee.Teams.Remove(this);

        return this;
    }

    public virtual Team AddEmployee(Employee employee)
    {
        Employees.Add(employee);
        employee.Teams.Add(this);

        return this;
    }
}

Я хочу сопоставить это со следующим DTO.

public class EmployeeForm
{
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string EMail { get; set; }
    public string TeamName { get; set; }
    public int Id { get; set; }
}

Таким образом, TeamName - это тот, кого нужно сопоставить.

Я использую следующий код сопоставления:

Mapper.CreateMap<Employee, EmployeeForm>()
    .ForMember(dest=>dest.TeamName, opt => opt.MapFrom(s=>s.Teams.FirstOrDefault().Name));
var mappedresult = Mapper.Map<List<Employee>, List<EmployeeForm>>(result);

Проблема в члене Employee.Teams. Кстати, коллекция Teams очень загружена. Так оно и есть.

Когда Teams имеет значение Null, я получаю исключение NullReference.

Как я могу сопоставить название команды с DTO?

РЕДАКТИРОВАТЬ: На данный момент я покинул Automapper и вместо этого использую этот громоздкий код:

var result = _repository.GetAllView();

var employeeForms = new List<EmployeeForm>();
foreach (Employee employee in result)
{
    var employeeAdded = false;
    foreach (var team in employee.Teams)
    {
        employeeForms.Add(new EmployeeForm
          {
              EMail = employee.EMail,
              FirstName = employee.FirstName,
              LastName = employee.LastName,
              TeamName = team.Name
          });
        employeeAdded = true;
    }

    if (!employeeAdded)
    {
        employeeForms.Add(new EmployeeForm
        {
            EMail = employee.EMail,
            FirstName = employee.FirstName,
            LastName = employee.LastName,
            TeamName = string.Empty
        });
    }
}
return View(employeeForms);

Для меня это пахнет мучением ...


person Rookian    schedule 23.02.2010    source источник


Ответы (1)


Вы получаете исключение nullreferenceexception из-за FirstOrDefault (). Name, поэтому вам нужно выполнить проверку на null после firstordefault и сообщить автомату, что вы хотите вернуть, когда null. Остальные части должны работать нормально.

person Paco    schedule 23.02.2010
comment
Как мне сделать это в делегате: /? Mapper.CreateMap ‹Сотрудник, EmployeeForm› () .ForMember (dest = ›dest.TeamName, opt =› opt.MapFrom (s = ›s.Teams! = Null? Return s.Teams.First (). Имя: строка. Пустой)); - ›Это не работает синхронно. - person Rookian; 23.02.2010
comment
Это похоже на компиляцию кода, но является ли пустая ссылка, исходящая от команд, нулевой или команды пусты? opt.MapFrom (s = ›s.Teams.FirstOrDefault () == null? string.Empty: s.Teams.FirstOrDefault (). Имя) - person Paco; 23.02.2010
comment
Команды могут быть нулевыми, значит, это происходит. - person Rookian; 23.02.2010
comment
1. Оно не может быть нулевым, когда я вижу ваш конструктор 2. Исключение nullreference будет генерироваться с источником параметра из firstordefault вместо имени - person Paco; 23.02.2010
comment
ах, извини, я ошибся, я проверил бота, и он работает: o Спасибо! - person Rookian; 23.02.2010