【发布时间】:2019-08-07 02:10:27
【问题描述】:
我需要从 EF Core 调用的存储过程中读取结果,其中包括用于电子表格格式化目的的内容,例如只有空值的行。我的代码大部分都在工作,但是有两列在我包含它们时会导致查询失败。
这是我的模型类(为简洁起见,仅包括一些道具):
public class StoredProcRecord
{
[Column("Prod Line")]
public string ProductLine { get; set; }
[Column("Current Sales")]
public decimal? CurrentSales { get; set; }
[Column("Current Margin $")]
public decimal? CurrentMargin { get; set; }
}
如果我从 SQL Server Management Studio 运行存储过程,这是部分输出的 sn-p:
以下是我在 db 上下文中使用 EF Core 将类型注册为实体模型的方法:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Query<StoredProcRecord>();
}
这是我调用存储过程的方式:
return _context.Query<StoredProcRecord>().FromSql("EXECUTE my_stored_proc").ToList();
在此示例中,EF Core 在尝试调用 FromSql() 时总是抛出异常,并显示以下消息:
结果中不存在所需的列“当前保证金 $” 'FromSql' 操作。
根据EF Core docs,只要列可以为空,则不需要。然而,我收到声称需要“当前保证金 $”的例外情况。它也只发生在CurrentMargin 属性上,而不是CurrentSales 属性,它使用相同的类型。如果我删除 CurrentMargin,整个事情都会正常工作,而我只是缺少那个属性。
我尝试使用[Column(Order = 2)] 代替命名列,认为列名中的美元符号可能与它有关,但这会导致:
所需的列“CurrentMargin”未出现在结果中 'FromSql' 操作。
同时包含 order 和 name 会导致相同类型的错误。
值得注意的是,这不是我可以选择对其进行更新的存储过程。
CurrentMargin 属性与CurrentSales 相比有什么不同导致它像这样失败?我需要一些特殊的方法来处理列名中的美元符号吗?我是否完全错过了其他东西?
编辑:
这是存储过程最后的一个 sn-p,输出结果表。我将其包括在内是为了表明“当前保证金 $”确实是列名之一。我实际上是直接从存储过程中复制/粘贴的,只是为了确保我没有输入错误的列名。
BEGIN
-- bulk of stored procedure that builds #tmp_tbl omitted for length
SELECT
'Prod Line' = pl_key,
'Current Sales' = curr_sales,
'Current Margin $' = curr_margin
FROM #tmp_tbl
END
【问题讨论】:
-
Yet, I receive that exception that claims "Current Margin $" is required.-不,这不是!它实际上是在查询返回的输出中没有名为Current Margin $的列。 -
看起来 SP 返回的列名不是 'Current Margin $'。检查 $ 后的空格或其他符号。
-
问题是,我已经尝试过帖子中的代码,它可以像这样
CREATE PROCEDURE [dbo].[my_stored_proc] AS DECLARE @DATA TABLE(ProductLine VARCHAR(20), CurrentSales decimal, CurrentMargin decimal); insert into @DATA values('1', 1, 1); insert into @DATA values('2', 2, 2); insert into @DATA values('3', 3, 3); insert into @DATA values('4', 4, 4); insert into @DATA values(null, null, null); select T.ProductLine [Prod Line], T.CurrentSales [Current Sales], T.CurrentMargin [Current Margin $] from @DATA T; RETURN 0与测试 SP 一起使用,换句话说,它不会重现 -
@IvanStoev 嗯...您的样本确实如我所料。不幸的是,这只会让原始问题更加令人费解,因为来自原始 SP 的错误专门将“当前保证金 $”作为问题字段,但无论如何我都无法让您的 SP 以任何类似的方式失败尝试修改它。
-
你知道吗,你的 SP 的
SELECT看起来很奇怪,可能返回的所有列名都不是你所期望的 - EF Core 只报告 alphabetical 中第一个丢失的列名i> 订购。要查看你得到了什么,请执行以下 sn -pvar cn = _context.Database.GetDbConnection(); var cmd = cn.CreateCommand(); cmd.CommandText = "my_stored_proc"; cn.Open(); var dr = cmd.ExecuteReader(); var cols = Enumerable.Range(0, dr.FieldCount).Select(i => dr.GetName(i)).ToList();并检查调试器中的cols变量。
标签: c# sql-server entity-framework ef-core-2.0