0

Я использую AutoMapper для сопоставления с моим DataLayer (EF6 DbFirst AutoGenerated layer) на моем ModelLayer (Pocos/Dtos). Одна вещь, которую я смущает, - это использование хранимых процедур, которые они возвращают сложный объект, такой как Customer_GetCustomers_Result, поэтому я должен сопоставить это с моим CustomerPoco с AutoMapper, и я теряю свойства объекта внешнего ключа, такие как Customer.Address, поскольку они не находятся в моем сложном типе ,Сохраненная процедура возвращает сложный тип, я использую AutoMapper для сопоставления его с моей моделью, но объекты внешнего ключа не получают

Вот пример моего CustomerPoco:

public class Customer 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Phone { get; set; } 
    public string Fax { get; set; } 
    public string Website { get; set; } 
    public int AddressId { get; set; } 

    // THESE END UP NOT GETTING SET 
    public List<CustomerContact> Contacts { get; set; } 
    public Address Address { get; set; } 
} 

В моем GetCustomers хранимого процедуру позволяет сказать, что я могу сделать что-то простое, как: SELECT * FROM ЗАКАЗЧИКА. Он возвращает сложный объект context.Customer_GetCustomers_Result. Затем мне нужно сопоставить этот сложный объект с моим CustomerPoco. Контакты и адрес не устанавливаются. Как мне это сделать?

Вот мои отображения для Клиента:

CreateMap<Customer, Model.Customer>() 
     .ForMember(dest => dest.Contacts, opt => opt.MapFrom(src => src.CustomerContacts)); 

    CreateMap<Customer_GetCustomers_Result, Model.Customer>(); 

Это на самом деле, возможно, был плохой вопрос. Я считаю, что если я действительно хочу использовать хранимые процедуры для возврата своих списков, мне нужно будет объединить и фактически вернуть свойства адреса в моем select, например ... a.Address1, a.Address2 и т. Д. Тогда есть способ чтобы сопоставить их с Model.Customer.Address отсюда, хотя все они разделены на отдельные свойства?

+0

Не могли бы вы показать сопоставления, которые вы установили? –

+0

Хорошо, я добавил их.Причина, по которой я добавил ForMember для контактов, состояла в том, что я изменил имя из CustomerContacts на Contacts в моей модели. Должен ли я добавить что-то к моим сопоставлениям, чтобы убедиться, что объект Address привязан? Я заметил, что автогенерируемый класс Customer_GetCustomers_Result не имеет в нем свойства объекта Address, как у Data.Customer и моего класса Model.Customer. Это имеет смысл, поскольку в большинстве случаев proc возвращает AddressId. Есть ли способ обойти это? – JTunney

ответ

1

Это на самом деле довольно тривиально, но вам, возможно, придется настроить конфигурацию AutoMapper. Ваша хранимая процедура может действительно только возвращать сглаженные результаты, но вы все равно можете передать все поля для всех отношений. Если вы хотите получить практически полную конфигурацию, вам просто нужно, чтобы ваша хранимая процедура возвращала имена свойств в сплющенном формате. Например, AddressCity вместо чего-то вроде City. Если объект Размечая из имеет свойство, как AddressCity, а объект Размечая к имеет свойство навигации Address, которая сама по себе имеет свойство City, AutoMapper будет автоматически заполнить это соответствующим образом. Если вы не хотите или не можете изменить имена столбцов, возвращаемые хранимой процедуры, то вам просто нужно настроить AutoMapper:

AutoMapper.Mapper.CreateMap<Customer_GetCustomers_Result, Custom>() 
    .ForMember(dest => dest.Address, opts => opts.MapFrom(src => new Address 
    { 
     City = src.City, 
     // etc. 
    }); 

Если у вас есть более сложные сценарии, как перечислимого свойства навигации, этот метод не будет работать. Лучше всего в этом случае сделать это несколькими шагами, так что вы используете одну хранимую процедуру для извлечения первичного объекта и всего, что можно сгладить с ним. При этом вы наберете нужный тип. Затем используйте отдельную хранимую процедуру для поиска перечислимого элемента на основе идентификатора первичного объекта или чего-то еще и сопоставьте их с перечисляемым свойством на ранее отображенном объекте.

+0

Это именно то, что мне нужно было знать. Я смотрел документацию AutoMapper и видел, что если у вас есть объект внутри объекта, он сможет сопоставить его, если именование правильное. Я должен был подумать, чтобы просто вернуть мои столбцы из моей Get stored proc с правильными именами. Большое спасибо! – JTunney

1

Я думаю, у вас есть два отдельных вопроса, которые вы можете задать здесь. Первый способ - вернуть хранимую процедуру и связать все данные с вашим сложным типом EF. Есть пара статей here (blog) и here (CodeProject), которые должны помочь. По существу, напишите свой sproc, чтобы вернуть несколько наборов результатов, и пару строк кода, чтобы перейти к следующему набору результатов и прочитать его в контексте.

Чтобы получить нужное сопоставление с AutoMapper, вам необходимо добавить карты для каждого типа, который вы используете в качестве свойства, также (например, карту из вашего типа EF «Адрес» в тип вашего адреса POCO).