【问题标题】:EF stored procedure with dynamic number of columns in result set结果集中具有动态列数的 EF 存储过程
【发布时间】:2012-10-23 04:26:11
【问题描述】:

首先我应该注意到我是 ASP.NET 的新手(不过,我对 C# 有一些经验)和实体框架。我在一个学校项目上工作,有一个包含能源消耗数据的非常复杂的数据库。我需要的那些(I 导入、E 导出、无功功率CL)以二进制压缩的形式存储在一列中,因此为了将它们取出,我必须使用一个存储过程,该过程调用自定义中的一些方法程序集以解压缩列并恢复数据。

存储过程有 4 个参数:

@identify int,
@startTime datetime,
@endTime datetime,
@args nvarchar(60) -- "Selector"

selector 相当特别,它是一个参数,您可以在其中指定您想要的结果集中的内容,例如'i' 仅用于导入列,'i,e' 用于导入和导出。他们这样设计它是因为如果您只需要一列而不是所有列(因为压缩数据的存储方式),它会更快。

因此,我创建了一个名为 EnergyConsumptionDBModel 的 ADO.NET 实体模型,导入了存储过程并为存储过程返回类型创建了复杂类型 EnergyConsumptionResult,如下所示:

public partial class EnergyConsumptionResult
{
    public System.DateTime Time { get; set; }
    public double I { get; set; }
    public double E { get; set; }
    public double L { get; set; }
    public double C { get; set; }
}

Time 列始终存在于结果集中,但其余部分取决于存储过程的 @args 参数。例如,如果我选择'i,e,c,l' 作为参数,它将返回列Time, I, E, C, L,一切都很好,但如果我选择例如'i',它返回Time, I,这给了我一个例外:

数据读取器与指定的“EnergyConsumptionDBModel.EnergyConsumptionResult”不兼容。
类型的成员“E”在数据读取器中没有对应的列同名。

所以问题是,有没有一些简单的方法可以解决这个问题?某种复杂类型的动态结果映射,或者告诉我的同事谁设计了存储过程以使其返回所有列,无论@args 中的所有列,但将未使用的列留空,这是我的项目的解决方案。领导可能不喜欢。感谢您的帮助。

【问题讨论】:

  • 一定要使用实体框架吗?您可以使用Dapper 以动态类型捕获结果。
  • @GertArnold 实体框架不是必需的。虽然我已经通过使用包装程序解决了我的问题(我不太喜欢它,但它确实有效),但我一定会看看这个。
  • @RiZe 你有没有想出一个可以分享的解决方案?我有同样的问题。谢谢
  • @PostureOfLearning 实际上是的,有点。我创建了一个包装存储过程,其中创建了一个包含所有列的表,然后为@args 中存在的每个变量(I、E、L、C)执行原始存储过程。然后,该表在不需要的列中返回 NULL 值。不幸的是,我可能找不到那段代码,因为原始存储过程在开发过程中被放弃了。

标签: sql-server asp.net-mvc entity-framework


【解决方案1】:

我认为不可能在 EF 中自动映射具有可变列数的结果集。您在设计时指定映射,EF 依赖于此。您可以做的是返回所有列,但将不返回数据的列设置为空。您可以尝试使用直接执行存储过程并在 ObjectContext (http://msdn.microsoft.com/en-us/library/dd466384.aspx) 上使用 Translate 方法进行具体化,但我认为这种方法也将在您的读者中使用列对应于属性名称。

【讨论】:

  • 看起来我将不得不围绕该存储过程创建一个包装过程。我的项目负责人不喜欢以这种方式修改存储过程本身的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多