我正在研究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
的研究,我们可以使用ToDictionaryAsync
或ToLookupAsync
来做到这一点,但我仍然无法做到这一点。
此外,我还需要异步执行此操作。
答案 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)
});