C# 实体框架核心:如何使用存储过程的结果集,并通过维护异步将其映射到对象和对象的对象
我正在研究实体框架核心 我的任务是执行一个存储过程,并根据该存储过程的结果填充DTO。我很难用存储过程结果映射DTO类的属性,尤其是当我必须映射它的object(另一种类类型)属性时 考虑以下DTO类C# 实体框架核心:如何使用存储过程的结果集,并通过维护异步将其映射到对象和对象的对象,c#,sql,entity-framework,.net-core,entity-framework-core,C#,Sql,Entity Framework,.net Core,Entity Framework Core,我正在研究实体框架核心 我的任务是执行一个存储过程,并根据该存储过程的结果填充DTO。我很难用存储过程结果映射DTO类的属性,尤其是当我必须映射它的object(另一种类类型)属性时 考虑以下DTO类 public class Contact { public int Id { get; set; } public string Name { get; set; } public string EmailAddress { get; set; } public C
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 packageStoredProcedureEFCore
执行存储过程
以下是调用存储过程的代码:
Task<Contact> contactDetails = null;
_context.LoadStoredProc("usp_GetContactDetails")
.Exec(r =>
{
contactDetails = r.FirstOrDefaultAsync<Contact>();
});
// TODO: need to populate Company object
Task contactDetails=null;
_context.LoadStoredProc(“usp_GetContactDetails”)
.Exec(r=>
{
contactDetails=r.FirstOrDefaultAsync();
});
//TODO:需要填充公司对象
这段代码适用于Id、名称、电子邮件地址,但不适用于公司属性,因为我必须转到公司对象并填充该对象属性
根据我对StoredProcedureEFCore
的研究,我们可以使用ToDictionaryAsync
或ToLookupAsync
来实现这一点,但我仍然无法做到
另外,还有一件事我必须异步完成。首先,我认为不可能使用ToDictionaryAsync或ToLookupAsync映射StoredProcedureFore中的关系 但您可以创建自己的映射函数,如:
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;
}
公共静态异步任务映射联系人(DbDataReader dataReader){
if(等待dataReader.ReadAsync()&&dataReader.HasRows){
触点=新触点();
contact.Id=dataReader.GetInt32(dataReader.GetOrdinal(“Id”);
contact.Name=dataReader.GetString(dataReader.GetOrdinal(“Name”);
contact.EmailAddress=dataReader.GetString(dataReader.GetOrdinal(“EmailAddress”);
公司=新公司();
company.Id=dataReader.GetInt32(dataReader.GetOrdinal(“CompanyId”);
company.Name=dataReader.GetString(dataReader.GetOrdinal(“CompanyName”);
联系人:公司=公司;
回接;
}
返回null;
}
并将其作为参数传递给Exec调用
Task<Contact> contactDetails = null;
_context.LoadStoredProc("usp_GetContactDetails")
.Exec(r =>
{
contactDetails = MapContact(r)
});
Task contactDetails=null;
_context.LoadStoredProc(“usp_GetContactDetails”)
.Exec(r=>
{
contactDetails=MapContact(r)
});
使用存储过程的原因是什么;为什么不直接在上下文中编写查询?另外,您的公司是模型中的一个嵌套属性,并且在结果中变平,您必须手动执行此操作r.Select(x=>newcontact{..})
我必须使用存储过程。我不能使用LINQ或直接查询。你能使用“选择”吗?不,没有“选择”选项。这可以是一个选项,但不太通用。感谢您提供此解决方案!