【问题标题】:Entity Framework - Mapping return from stored procedure which returns different set of output实体框架 - 从返回不同输出集的存储过程映射返回
【发布时间】:2021-08-23 20:39:08
【问题描述】:

我有一个以这种格式返回数据的存储过程

IF @Count = 0 
    SELECT 0
ELSE IF @COUNT = 1 
    SELECT 1
ELSE 
    SELECT 'Col_1', 'Col_2', 'Col_3' 
    FROM [TABLE_NAME] 
    WHERE [CONDITION]

当尝试在实体框架中为此“函数导入”映射结果时,如果我将返回设置为由“Col_1”、“Col_2”、“Col_3”组成的复杂类型,则当@Count 更大时它工作得很好大于 1。对于 @Count 0 或 1,我收到有关缺少列的错误。

如果我将返回值设置为整数,它适用于 @count 0 和 1,但不适用于 @Count > 1

我尝试将复杂类型中的列设置为“可空”,还添加了一个设置为整数的空白列,但没有成功。

我在这里唯一的选择是修改 SP 以始终返回一组结果吗?还是用老式的 ADO.NET 方式调用存储过程?

【问题讨论】:

  • 这是这样做的最令人信服的原因之一 - 理想情况下,存储过程应该始终返回相同的数据“形状”,例如相同数量和类型的列
  • 我很好奇。如果你运行SELECT * FROM Person WHERE Name = '...',有时你有 10 个人记录,而其他时候你只有一个数字 1,作为一个聪明人,你会感到困惑吗?现在想象一下 EF 必须有多么混乱,总是期望它可以变成一个 Person 实体..
  • 我认为了解这里的逻辑有多糟糕的一个好方法是考虑你会如何命名这样的 sproc,以便以前没有使用过它的人可以很容易地理解它的目的。像GetThingsByName 这样的名称可以非常清楚地说明过程/函数的作用。你会怎么称呼这个sproc?没有一个简单的名称可以清楚地表明它的用途,所以它是一个糟糕的 sproc。
  • 这个想法是如果没有找到执行条件的匹配项,则返回 0,完全匹配返回 1,如果存在超过 1 个匹配项,则返回整个结果集。我们的数据库认为这是最好的方法,但它与实现代码并不能很好地配合。我会尝试更新这个存储过程

标签: c# vb.net entity-framework stored-procedures


【解决方案1】:

是的。您已告诉 EF,此过程返回一个看起来像 X 的结果集,然后在某些情况下这不是真的。

我完全看不出有任何令人信服的理由来编写一个执行此操作的存储过程;如果您不想返回 X,则引发错误

如果您想处理这种复杂/错综复杂的逻辑,那么 EF 不是工具

即使您在想要返回 0 或 1 的情况下返回了一个类型兼容列之一设置为该值的结果集(例如,如果您经常返回 10 个 Person 行但在在这些情况下,您返回一个 Person 行,除了 Age 为 0 或 1 之外,该行全部为空)然后您仍然必须了解并处理客户端中的疯狂逻辑。接管您的代码的新开发人员会坐在那里摸不着头脑,然后说“EF 出了点问题;我写了context.Person.Where(p => p.Name = "kazinsky"),我只是让一个年龄为 1 岁的人回来,但我可以在数据库中看到满满的数据,23岁,wtf”

我在这里唯一的选择是修改 SP 以始终返回一组结果吗?还是用老式的 ADO.NET 方式调用存储过程?

如果我在我正在维护的项目中发现这种代码,我会把它全部撕掉——这是一个彻头彻尾的糟糕主意。您在这里唯一合乎逻辑的选择是更改存储过程。其他任何事情都只会延续有问题的设计。最简单的方法是更改​​存储过程,使其引发错误“输入参数匹配 0 条记录”/“输入参数匹配 1 条记录;此存储过程只能使用匹配 2 条或更多条记录的参数调用,因为...”

善待有一天会坐在你椅子上的人:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多