列映射到未命名列

问题描述

我正在使用 Entity Framework Core 3 来尝试执行存储过程。我需要获取存储过程的返回值,但是,在存储过程中,没有名称。这是我执行存储过程的代码

var data = await _context.Set<ArfmCreateEditRequestDto>()
            .FromsqlRaw(@"ARFMCreateEditRequest {0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19},{20},{21},{22},{23},{24},{25}","Add",accountType,srIdentifier,srCheckDigit,arIdentifier,arCheckDigit,customerName,changeCustomerName,supplierId,amount,paymentMethod,addresstype,address1,address2,address3,address4,country,city,state,zip,statusCode,createdBy,invoiceDate,approvedBy,comments,updateId).ToListAsync();

这是我的 ArfmCreateEditRequestDto 课:

public class ArfmCreateEditRequestDto
{
    [Column(Order = 0)]
    public string Retval { get; set; }
}

当我在 sql Server 上执行此操作时,我得到以下结果:

--------------------------------------
| (No column name)                   |
--------------------------------------
| RequestID: 36 Succesfully Added    |
--------------------------------------

当我运行我的程序时,我得到一个异常

"system.invalidOperationException: The required column 'Retval' was not present in the results of a 'Fromsql' operation."

如果我改成这样:

    [Column("",Order = 0)]
    public string Retval { get; set; }

然后我得到这个异常:

"System.ArgumentException: The argument 'name' cannot be null,empty or contain only whitespace. (Parameter 'name')"

我真的认为第一件事会起作用,实体框架只会将数据从订单位置 0 映射到我的财产,但显然没有。

所以我的问题是,如果列在存储过程中未命名,如何捕获我的返回值?请注意,我根本无法更改存储过程。

解决方法

这不可能。使用上有一些限制FromSqlRaw

1-SQL 查询必须返回实体类型的所有属性的数据。

2-结果集中的列名必须与属性映射到的列名匹配。请注意,此行为与 EF6 不同。 EF6 忽略了原始 SQL 查询的属性到列映射,结果集列名必须与属性名匹配

基于此链接:https://docs.microsoft.com/en-us/ef/core/querying/raw-sql

但我认为你可以包装存储过程并将结果插入到临时表中,其中任意列是这样的:

var data = await _context.Set<ArfmCreateEditRequestDto>()
            .FromSqlRaw(@"create table #tmp( Retval nvarchar(128) ) insert into #tmp( Retval ) exec ARFMCreateEditRequest {0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19},{20},{21},{22},{23},{24},{25} select Retval from #tmp","Add",accountType,srIdentifier,srCheckDigit,arIdentifier,arCheckDigit,customerName,changeCustomerName,supplierId,amount,paymentMethod,addressType,address1,address2,address3,address4,country,city,state,zip,statusCode,createdBy,invoiceDate,approvedBy,comments,updateId).ToListAsync();