.net 已经有一个打开的DataReader与此连接关联,必须在rawsql语句中首先关闭该连接

db2dz4w8  于 2023-06-25  发布在  .NET
关注(0)|答案(2)|浏览(95)

executeSql引发标题异常。我必须如何在. net core中使用raw sql来检索数据集并处理它?

public async Task<IActionResult> Refresh_Formatos()
    {            
        using (var context = _context)
        {
            var padre = context.Database.SqlQuery<int>(
                $@"SELECT id
                 FROM pds_etiquetas where nombre='FORMATOS' and tipo = 'Cat'
                 ").ToList();
            int padre_id = padre[0];
           
            var formatos = context.Database.SqlQuery<string>(
                $@"SELECT xdescripcion
                 FROM vc00_formatos a
                 left join pds_etiquetas c on a.xdescripcion=c.Nombre and {padre_id}=c.PadreId and c.tipo = 'Val'
                 where c.id is null
                 order by xdescripcion");
            context.Database.CloseConnection();
            foreach (var formato in formatos)
            {
                var affectedRows = context.Database.ExecuteSql(
                                    $@"INSERT INTO [imp].[pds_etiquetas]
                                           ([Nombre]
                                           ,[Tipo]
                                           ,[PadreId])
                                     VALUES
                                           ('{formato}'
                                           ,'Val'
                                           ,{padre_id})
                    ");
            }
        }                        
        return Ok();            
    }
xxslljrj

xxslljrj1#

SqlQuery返回一个IEnumerable,该IEnumerable将在枚举查询时执行查询。您是在关闭连接后枚举它的,因此它会在关闭连接后尝试执行查询。
在关闭连接之前使用ToList()可以修复它,因为它会在调用该连接时枚举它。即:

var formatos = context.Database.SqlQuery<string>(
            $@"SELECT xdescripcion
             FROM vc00_formatos a
             left join pds_etiquetas c on a.xdescripcion=c.Nombre and {padre_id}=c.PadreId and c.tipo = 'Val'
             where c.id is null
             order by xdescripcion").ToList();
        context.Database.CloseConnection();

https://learn.microsoft.com/en-us/dotnet/api/system.data.entity.database.sqlquery?view=entity-framework-6.2.0

e4eetjau

e4eetjau2#

您需要将formatos放入List

  • 还应该正确地参数化查询
  • 您应该使用Async函数,但旧EF似乎不提供SqlQueryAsync
public async Task<IActionResult> Refresh_Formatos()
{            
    using (var context = _context)
    {
        var padre_id = context.Database.SqlQuery<int>(
            @"SELECT id
             FROM pds_etiquetas
             where nombre = 'FORMATOS'
               and tipo = 'Cat'
             ").First();
       
        var formatos = context.Database.SqlQuery<string>(
            @"SELECT xdescripcion
             FROM vc00_formatos a
             left join pds_etiquetas c on a.xdescripcion=c.Nombre and @padre_id = c.PadreId and c.tipo = 'Val'
             where c.id is null
             order by xdescripcion",
           new SqlParameter("@padre_id", SqlDbType.Int) { Value = padre_id }
           ).ToList();

        foreach (var formato in formatos)
        {
            var affectedRows = await context.Database.ExecuteSqlAsync(
                @"INSERT INTO imp.pds_etiquetas
                      (Nombr, Tipo, PadreId)
                  VALUES (@formato, 'Val', @padre_id)
                ",
                new SqlParameter("@padre_id", SqlDbType.Int) { Value = padre_id },
                new SqlParameter("@formato", SqlDbType.VarChar, 250) { Value = formato }
           );
        }
    }                        
    return Ok();            
}

话虽如此,你不需要做任何这些,你可以只做一个大的加入INSERT
您还可以将LEFT JOIN更改为NOT EXISTS,并且应该使用新的上下文而不是现有的上下文。

public async Task<IActionResult> Refresh_Formatos()
{            
    using var context = new YourContextHere();
    var affectedRows = await context.Database.ExecuteSqlAsync(@"
INSERT INTO imp.pds_etiquetas
  (Nombr, Tipo, PadreId)
SELECT
  a.xdescripcion,
  'Val',
  p.id
FROM pds_etiquetas p
CROSS JOIN vc00_formatos a
where p.nombre = 'FORMATOS'
  and P.tipo = 'Cat'
  AND NOT EXISTS (SELECT 1
    FROM pds_etiquetas c
    WHERE a.xdescripcion = c.Nombre
      and p.id = c.PadreId
      and c.tipo = 'Val'
);
  ");
    return Ok();            
}

相关问题