实体框架核心:如何使用存储过程的结果集并通过保持异步将其映射到对象和对象的对象

时间:2018-10-14 08:49:15

标签: c# sql entity-framework .net-core entity-framework-core

我正在研究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,名称,电子邮件地址,但不适用于公司属性,因为我必须去公司对象并填充该对象属性。

根据我对StoredProcedureEFCore的研究,我们可以使用ToDictionaryAsyncToLookupAsync来做到这一点,但我仍然无法做到这一点。

此外,我还需要异步执行此操作。

1 个答案:

答案 0 :(得分:1)

首先,我认为无法使用ToDictionaryAsync或ToLookupAsync在StoredProcedureEFCore中映射关系。

但是您可以创建自己的映射函数,例如:

 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)
    });