【问题标题】:Stored Procedures in LINQ-to-SQLLINQ-to-SQL 中的存储过程
【发布时间】:2011-06-16 13:09:01
【问题描述】:

我在返回结果列表的 SQL Server 数据库中有一个存储过程。此存储过程在 LINQ-to-SQL dbml 文件中公开。然后我尝试这样调用这个存储过程:

public List<MyObject> GetObjects()
{
  List<MyObject> objects = new List<MyObject>();
  using (DatabaseDataContext context = new DatabaseDataContext())
  {
    objects = context.GetObjectsFromDB();  // This is my problem line
  }
  return objects;
}

我的问题是,我不知道如何将存储过程的结果转换为List&lt;MyObject&gt;。 context.GetObjectsFromDB 返回 System.Data.Linq.ISingleResult&lt;sprocName&gt;。如何将存储过程的结果转换为我的强预定义类型列表?

谢谢!

【问题讨论】:

  • 请显示用于调用 sproc 的代码。
  • 附带说明:最初新建列表是不必要的(而且是浪费的),初始列表对象只会被 GC。

标签: c# sql-server linq stored-procedures


【解决方案1】:

试试这个,

public List<MyObject> GetObjects()
{

 using (DatabaseDataContext context = new DatabaseDataContext())
 {
 var objects = context.GetObjectsFromDB();  
 return new  List<MyObject>(objects);
 }
}

更新: 通过使用显式转换,它可以像这样完成

public List<MyObject> GetObjects()
{  
 using (DatabaseDataContext context = new DatabaseDataContext())
 {
  List<MyObject> objects = (List<MyObject>)context.GetObjectsFromDB();  
  return objects;
 }
}

【讨论】:

  • @Justin: HERE VAR 将您的对象隐式转换为所需类型,编译器将在运行时获取它。您也可以通过显式转换来做到这一点,并且在您的代码中没有定义任何铸造...
  • 啊,我明白你在做什么了。我对您原始版本中的List&lt;MyObject&gt; objects = new List&lt;MyObject&gt;(); 感到困惑,我认为这是不必要的。你实际上可以用return (List&lt;MyObject&gt;)context.GetObjectsFromDB(); 替换using 块中的所有内容,它会正常工作。
  • @贾斯汀:哦,是的,谢谢贾斯汀的更正。列表 对象 = 新列表();不是必需的,我没有看到它着急..我已经更新了它
【解决方案2】:

ISingleResult&lt;T&gt; 继承自 IEnumerable&lt;T&gt;。只要“T”代表 MyObject,您就应该能够遍历序列。如果 'T' 是不同的类型,我会在 MyObject 上放置一个构造函数,它采用 DB 类型并从中创建一个 MyObject。

您是否尝试在 SPROC 调用后删除断点以查看调试器对您返回的对象的说明?

【讨论】:

    【解决方案3】:

    Enumerable 类还有一个 ToList 成员函数,我通常用于此目的。 http://msdn.microsoft.com/en-us/library/bb342261.aspx

    另外,当使用 Linq to Sql 时,我总是检查结果是否为空。如果我期望一个列表,请在转换为列表之前检查计数是否大于零。

    public List<MyObject> GetObjects()
    {
      List<MyObject> objects = null; // no need to "new" here
      using (DatabaseDataContext context = new DatabaseDataContext())
      {
        var tmp = context.GetObjectsFromDB();
        if (tmp != null) 
        {
          if (tmp.Count() > 0)
          {
            objects = (List<MyObject>)tmp.ToList();
          }
        }
      }
      return objects;
    }
    

    同样,如果您只期望一个结果,请使用

    myObject = (MyObject)tmp.ToSingle();
    

    最后,您可能需要考虑将此函数包装在一个 try-catch 块中并捕获 SqlException 并适当地处理错误。

    由于开发应用程序的经验,我只提到了额外的错误处理 如果您没有额外的错误处理代码,它可能会崩溃!

    【讨论】:

      【解决方案4】:

      我知道为时已晚,但是......

      从 LINQ 的角度来看,SP(不为单个结果使用输出)将返回 DataSet,因此要创建一个列表,您必须从 SP 中指定返回字段:

      objects = context.GetObjectsFromDB().Select(x => x.MyObject);
      

      即SP返回的字段名称,如

      objects = context.GetObjectsFromDB().Select(x => x.Names);
      

      【讨论】:

        【解决方案5】:

        我遇到了同样的问题!

        我的解决方案是重新制作存储过程,用表变量替换时态表

        不自动映射 spAA_Result:

        CREATE PROCEDURE spAA 
        AS 
        CREATE TABLE #TABLETMP (ID INT, NAME varchar(50))
            ...
        SELECT * FROM #TABLETMP 
        

        自动映射正确类 spBB_Result:

        CREATE PROCEDURE spBB 
        AS 
        DECLARE @TABLETMP AS TABLE (ID INT, NAME varchar(50))
            ...
        SELECT * FROM @TABLETMP 
        

        【讨论】:

          【解决方案6】:

          是的,如下所示:

          List<string> listOfStrings = dbContext.spMyStoredProc().Select(x => x.Value).ToList<string>();
          

          或

          List<int> listOfInts = dbContext.spMyStoredProc().Select(x => x.Value).ToList<int>();
          

          【讨论】:

            猜你喜欢
            • 2012-08-14
            • 1970-01-01
            • 2010-10-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多