LINQ-to-SQL中的存储过程

4jb9z9bj  于 2023-09-28  发布在  其他
关注(0)|答案(7)|浏览(107)

我在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<MyObject>context.GetObjectsFromDB返回System.Data.Linq.ISingleResult<sprocName>。如何将存储过程的结果转换为强预定义类型的List?
谢谢你,谢谢!

zvms9eto

zvms9eto1#

试试这个

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;
 }
}
slhcrj9b

slhcrj9b2#

ISingleResult<T>继承自IEnumerable<T>。只要'T'表示MyObject,就应该能够遍历序列。如果'T'是一个不同的类型,我会在MyObject上放置一个构造函数,它接受DB类型并从中创建一个MyObject。
您是否尝试过在SPROC调用后删除断点,以查看调试器对您所返回的对象的说明?

gk7wooem

gk7wooem3#

Enumerable类也有一个ToList成员函数,我通常使用它。http://msdn.microsoft.com/en-us/library/bb342261.aspx
另外,当使用Linq to Sql时,我总是检查结果是否为null。如果我期望一个列表,在转换为列表之前检查计数是否大于零。

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();

最后,您可能需要考虑将此函数 Package 在try-catch块中,并捕获SqlException并适当地处理错误。
我只是提到了额外的错误处理,这是由于开发应用程序的经验,如果没有额外的错误处理代码,应用程序可能会崩溃!

neskvpey

neskvpey4#

我知道这是toooo晚,但....
从LINQ的Angular 来看,SP(不使用单个结果的输出)将返回DataSet,因此要创建列表,必须指定SP的返回字段:

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

即SP返回的字段名称,如

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

oalqel3c5#

我有同样的问题!
我的解决方案是重新制作存储过程,用表变量替换时态表
不MapspAA_结果:

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

AUTO MAP CORRECT CLASS spBB_Result:

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

wqnecbli6#

是什么将工作如下:

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

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

dbf7pr2w7#

我从SQL过程返回一个匿名类型,只有一个“txt id”,所以我使用了这个:

var connection = _dbContext.Database.GetDbConnection();
await connection.OpenAsync();

using var command = connection.CreateCommand();
command.CommandText = "GetIdsFromRange";
command.CommandType = CommandType.StoredProcedure;

var parameter = new SqlParameter("@changeDate", latestUpdateJob.LastUpadate);
command.Parameters.Add(parameter);

var result = new List<ChatDto>();

using var reader = await command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
    var dto = new ChatDto
    {
        TxtId = reader.GetInt32(reader.GetOrdinal("TxtId"))
        // Add other properties here as needed
    };

    result.Add(dto);
}

await connection.CloseAsync();

return result;

这是一个更详细的方法,但它绕过了Set()要求,并为您提供了从数据库阅读的更多控制。使用此方法时,请记住处理异常并确保正确的连接管理。这是一个更详细的方法,但它绕过了Set()要求,并为您提供了从数据库阅读的更多控制。使用此方法时,请记住处理异常并确保正确的连接管理。

相关问题