2016-10-21 4 views
1

У меня есть приложение, работающее на Entity Framework 6, Model First, работающее на старой базе данных.Использование AutoMapper для поиска связанного объекта и добавления его как свойства

В приложении у нас есть объект Person, у кого есть один или несколько Address -объектов. Они связаны с использованием дополнительных Tabel: PersonXAddress, как это:

Person 
    Id 
    Name 
    ... 


PersonXAddress 
    PersonId 
    AddressId 

Address 
    Id 
    Street 
    PostalCode 
    ... 

Использование AutoMapper, я добавил свойство к моим PersonDto "HomeAddres", который является адресом с AddressType == 1, как это:

Mapper.CreateMap<Person, PersonDto>() 
    .ForMember(x => x.HomeAddress, 
     o => o.MapFrom(y => y.PersonXAddresses 
       .Where(a => a.Address.AddressTypeId == 1) 
       .Select(x => x.Address).FirstOrDefault(); 

Так что в моем коде мне никогда не придется перебирать все разные адреса, чтобы найти Домашний адрес.

Но, я нахожу это очень медленным. Он создает HUGE sql query (около 50 строк sql) и запускает этот запрос в первый раз может занять до 30 секунд. После первого запуска запрос может занять почти 1 секунду, чтобы просто получить некоторые объекты Person из базы данных. Я обнаружил, что если я прокомментирую приведенное выше сопоставление, сгенерированный запрос срабатывает менее чем за секунду и возвращает результаты за несколько миллисекунд.

Есть ли лучший способ автоматического поиска HomeAddress? Можете ли вы предложить мне какую-либо помощь в том, что я могу улучшить?

спасибо

+0

Если вы создаете иностранный ключ, у вас будет доступный адрес. у вас не было никакой дополнительной строки для кода, чтобы получить адрес. –

+0

Иностранный ключ от человека к адресу невозможен, так как может быть несколько адресов. Дополнительный код там, чтобы убедиться, что мне не нужно перебирать каждый объект PersonXAddress только для того, чтобы найти HomeAddress каждый раз, когда –

+0

вы можете использовать отношение многих-многих, которое может помочь с третьим классом, который содержит первичные ключи обеих баз данных –

ответ

1

Вы выглядите так, как будто у вас проблема моделирования. У вас должен быть HomeAddress на вашей модели Person (и в таблице базы данных). Вы делаете предположение в этом запросе LINQ, что есть нулевой или один домашний адрес. Просто моделируйте это явно на уровне БД.

0

Попробуйте делать это только с помощью LINQ:

var personDTO = context.Person 
       .Where(p => p.Id == 1) 
       .Select(p => new { 
        person = p, 
        homeAddress = p.PersonXAddresses 
           .FirstOrDefault(px => px.Address.AddressTypeID == 1) 
           .Address }) 
       .Select(pd > new PersonDto { 
        Id = person.Id 
        Name = person.Name, 
        ... 
        HomeAddress = homeAddress 
       }).ToList(); 

Кроме того, убедитесь, что у вас есть соответствующие индексы (AddressTypeID, и т.д.).