Entity Framework Core: как использовать набор результатов хранимой процедуры и сопоставить его с объектом и объектом объекта, поддерживая асинхронность - PullRequest
0 голосов
/ 14 октября 2018

Я работаю над Entity Framework Core.

Моя задача - выполнить хранимую процедуру и заполнить DTO на основе результата этой хранимой процедуры.Мне сложно сопоставить свойства класса DTO с результатом хранимой процедуры, особенно когда мне нужно сопоставить это свойство объекта (другого типа класса).

Рассмотрим следующие классы DTO

public class Contact
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public Company Company { get; set; }
}

public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Мой SQL-запрос для хранимой процедуры:

SELECT
    Id                  = contact.id,
    Name                = LTRIM(RTRIM(contact.name)),
    EmailAddress        = LTRIM(RTRIM(contact.email)),
    -- company information
    CustomerId          = contact.cust_id
    CustomerName        = customer.name
FROM
    contact 
INNER JOIN
    customer ON contact.cust_id = customer.cust_id

Я использую пакет NuGet StoredProcedureEFCore для выполнения хранимой процедуры.

Вот код для вызова хранимой процедуры:

Task<Contact> contactDetails = null;

_context.LoadStoredProc("usp_GetContactDetails")
        .Exec(r =>
        {
            contactDetails = r.FirstOrDefaultAsync<Contact>();
        });

// TODO: need to populate Company object

Этот код работает для Id, Name, EmailAddress, но не для свойства Company, поскольку мне нужно перейти к объекту компании и заполнить свойства этого объекта.

Основано на моих исследованиях StoredProcedureEFCore, мы можем сделать это, используя ToDictionaryAsync или ToLookupAsync, но я все еще не могу этого сделать.

Плюс, еще одна вещь, которую я должен сделать это асинхронно.

1 Ответ

0 голосов
/ 14 октября 2018

Прежде всего, я не думаю, что можно отобразить отношения в StoredProcedureEFCore с помощью ToDictionaryAsync или ToLookupAsync.

Но вы можете создать свою собственную функцию отображения, например:

 public static async Task<Contact> MapContact(DbDataReader dataReader){
    if(await dataReader.ReadAsync() &&  dataReader.HasRows){
        Contact contact = new Contact();
        contact.Id =  dataReader.GetInt32( dataReader.GetOrdinal("Id"));
        contact.Name = dataReader.GetString(dataReader.GetOrdinal("Name"));
        contact.EmailAddress = dataReader.GetString(dataReader.GetOrdinal("EmailAddress"));
        Company company = new Company();
        company.Id = dataReader.GetInt32(dataReader.GetOrdinal("CompanyId"));
        company.Name = dataReader.GetString(dataReader.GetOrdinal("CompanyName"));
        contact.Company = company;
        return contact;
    }
    return null;
}

И укажите его как параметр для вашего вызова Exec

Task<Contact> contactDetails = null;

_context.LoadStoredProc("usp_GetContactDetails")
    .Exec(r =>
    {
        contactDetails = MapContact(r)
    });
...