简体   繁体   English

从 Entity Framework Core 3.0 调用存储过程

[英]Calling Stored Procedures from Entity Framework Core 3.0

I have a number of stored procedures which all have a number of parameters and execute a complex select statement where the results exactly match a table or view.我有许多存储过程,它们都有许多参数并执行复杂的 select 语句,其中结果与表或视图完全匹配。 I would like to map the result set to Entities.我想将 map 的结果集设置为实体。 This worked fine with version 2.2 but I can't get it to work with EFCore 3.0.这适用于 2.2 版,但我无法让它与 EFCore 3.0 一起使用。

My code is this:我的代码是这样的:

SqlParameter regionId = p.RegionId.HasValue && p.RegionId.Value != 0 ? new SqlParameter( "@RegionId", p.RegionId.Value ) : new SqlParameter( "@RegionId", System.DBNull.Value );

… (other parameters omitted for clarity, but all SqlParameters)

var contacts = await _context.PersonSearchViewSearch.FromSqlRaw( "EXECUTE [dbo].[PersonSearchView_Search] @RegionId, @RecordId, @Surname, @Firstname, @PostCode, @HomePhone, @WorkPhone, @MobilePhone, @EMail, @IncludePatients, @IncludeContacts, @IncludeEnquiries, @AllowedRegions, @IncludeOtherRegions, @IncludeDisallowedRegions, @FirstNameMP, @FirstNameAltMP, @SurnameMP, @SurnameAltMP", regionId, id, surname, forename, postcode, homePhone, workPhone, mobilePhone, email,includePatients, includeContacts, includeEnquiries, allowedRegions, includeOtherRegions,includeDisallowedRegions, forenameMP, forenameAltMP, surnameMP, surnameAltMP ).ToListAsync();

In EF Core 3.0 this generates the following SQL (which isn't valid):在 EF Core 3.0 中,这会生成以下 SQL(无效):

exec sp_executesql N'SELECT [p].[Address1], [p].[Address2], [p].[Address3], [p].[Address4], [p].[CarerOrProfessionalId], [p].[City], [p].[ContactId], [p].[Discriminator], [p].[EMail], [p].[EnquiryId], [p].[FirstName], [p].[FirstNameAltMP], [p].[FirstNameMP], [p].[HomePhone], [p].[MobilePhone], [p].[PatientId], [p].[PostCode], [p].[PreferredPhone], [p].[PreferredPhoneNo], [p].[RegionId], [p].[RegionName], [p].[SalutationId], [p].[SearchId], [p].[Surname], [p].[SurnameAltMP], [p].[SurnameMP], [p].[Title], [p].[WorkPhone], [p].[IsAllowed], [p].[IsPrimaryRegion]
FROM (
    EXECUTE PersonSearchView_Search @RegionId,@RecordId,@Surname,@Firstname,@PostCode,@HomePhone,@WorkPhone,@MobilePhone,@EMail,@IncludePatients,@IncludeContacts,@IncludeEnquiries,@AllowedRegions,@IncludeOtherRegions,@IncludeDisallowedRegions,@FirstNameMP,@FirstNameAltMP,@SurnameMP,@SurnameAltMP
) AS [p]
WHERE [p].[Discriminator] = N''PersonSearchViewSearch''',N'@RegionId int,@RecordId nvarchar(4000),@Surname nvarchar(6),@Firstname nvarchar(4000),@PostCode nvarchar(4000),@HomePhone nvarchar(4000),@WorkPhone nvarchar(4000),@MobilePhone nvarchar(4000),@EMail nvarchar(4000),@IncludePatients bit,@IncludeContacts bit,@IncludeEnquiries bit,@AllowedRegions nvarchar(8),@IncludeOtherRegions bit,@IncludeDisallowedRegions bit,@FirstNameMP nvarchar(4000),@FirstNameAltMP nvarchar(4000),@SurnameMP nvarchar(3),@SurnameAltMP nvarchar(3)',@RegionId=1,@RecordId=NULL,@Surname=N'smith%',@Firstname=NULL,@PostCode=NULL,@HomePhone=NULL,@WorkPhone=NULL,@MobilePhone=NULL,@EMail=NULL,@IncludePatients=1,@IncludeContacts=1,@IncludeEnquiries=1,@AllowedRegions=N'1,2,6,11',@IncludeOtherRegions=0,@IncludeDisallowedRegions=0,@FirstNameMP=NULL,@FirstNameAltMP=NULL,@SurnameMP=N'SM0',@SurnameAltMP=N'XMT'

The stored procedures are too complex to try and write with Linq to SQL.存储过程太复杂,无法尝试使用 Linq 到 SQL 编写。

The only workaround I currently have is to go back to SqlCommand / SqlDataReader method, but this requires writing a lot of additional code to map the results back into an entity.我目前唯一的解决方法是将 go 返回到SqlCommand / SqlDataReader方法,但这需要将大量附加代码写入 map 将结果返回到实体中。

Is there a better way to do this in EF Core 3.0?在 EF Core 3.0 中是否有更好的方法来执行此操作?

For anyone else coming across this issue, I tracked it down to my definition of "PersonSearchViewSearch" being a derived class from another view.对于遇到此问题的其他人,我将其追溯到我对“PersonSearchViewSearch”的定义,该定义是从另一个视图派生的 class。 I changed the definition to be a standalone class by copying all fields from the base class and this resolved the issue.我通过从基础 class 复制所有字段,将定义更改为独立的 class,这解决了问题。

This changed the generated SQL to be a simple Execute statement rather than a Select from an Execute.这将生成的 SQL 更改为简单的 Execute 语句,而不是来自 Execute 的 Select。

(EF Core 2.2 was happy with me using a derived class). (EF Core 2.2 对我使用派生类很满意)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM