【问题标题】:To update the field in database using Raw SQL?使用原始 SQL 更新数据库中的字段?
【发布时间】:2018-12-11 05:17:55
【问题描述】:

当我检查 where 条件时,我需要根据 senderId 更新 IsIgnored 字段,它无法识别我从循环中比较的 senderId。它会引发异常,例如列名“senderid”不明确。请指导我解决此问题。

  foreach (var senderId in senderIdList)
                    {
                        using (var context = new BSoftWEDIIContext())
                        {
                           var ediDocuments = context.EDIDocuments.SqlQuery("Update EDIDocument SET IsIgnored=1 from EDIDocument edi  inner JOIN  FileDetails files on edi.FileDetailsId = files.Id where edi.IsDeleted = 0 and  edi.SenderID =senderId and edi.DocumentTypeID != 3 and edi.DocumentTypeID != 5 and edi.DocumentTypeID != 2 and edi.IsIgnored = 0 and files.IsDeleted = 0" );

                        }

试过这样:

 var ediDocuments = context.EDIDocuments.SqlQuery("Update EDIDocument SET IsIgnored=1 from EDIDocument edi  inner JOIN  FileDetails files on edi.FileDetailsId = files.Id where edi.IsDeleted = 0 and  edi.SenderID ='149825353' and edi.DocumentTypeID != 3 and edi.DocumentTypeID != 5 and edi.DocumentTypeID != 2 and edi.IsIgnored = 0 and files.IsDeleted = 0", new SqlParameter
                            {
                                ParameterName = "senderId",
                                DbType = System.Data.DbType.String,
                                Value = senderId
                            });


  foreach (var senderId in senderIdList)
                    {

                        using (var context = new BSoftWEDIIContext())
                        {
                            var ediDocuments = context.EDIDocuments.SqlQuery("Update EDIDocument SET IsIgnored=1 from EDIDocument edi  inner JOIN  FileDetails files on edi.FileDetailsId = files.Id where edi.IsDeleted = 0 and  edi.SenderID=@senderId and edi.DocumentTypeID != 3 and edi.DocumentTypeID != 5 and edi.DocumentTypeID != 2 and edi.IsIgnored = 0 and files.IsDeleted = 0", new SqlParameter("@senderId", senderId));

【问题讨论】:

  • senderId 是什么?如果是参数,需要使用@前缀,使用SqlParameter;否则放置表别名以将其与其他表中的相同列名区分开来,例如files.senderId.

标签: c# sql sql-update rawsql


【解决方案1】:

您需要在查询中添加 sql 参数。

  using (var context = new BSoftWEDIIContext())
                {
                    foreach (var senderId in senderIdList)
                    {
                        context.EDIDocuments.ExecuteSqlCommand("Update EDIDocument SET IsIgnored=1 from EDIDocument edi  inner JOIN  FileDetails files on edi.FileDetailsId = files.Id where edi.IsDeleted = 0 and edi.SenderID=@senderId and edi.DocumentTypeID != 3 and edi.DocumentTypeID != 5 and edi.DocumentTypeID != 2 and edi.IsIgnored = 0 and files.IsDeleted = 0",
                            new SqlParameter
                            {
                                ParameterName = "senderId",
                                DbType = DbType.Int32,
                                Value = senderId
                            });
                    }
                }

【讨论】:

  • edi.SenderID=@senderId - 您确定在 sql 查询的参数中添加了 @ 符号吗?
  • 已添加,现在显示为数据读取器与指定的“BSoftWEDII.Data.EDIDocument”不兼容。类型的成员“Id”在数据读取器中没有同名的对应列。
  • 尝试使用 ExecuteSqlCommand 代替 SqlQuery。还要检查数据库中edi.SenderID、files.Id字段的类型和存在
  • 注意:你不能在你的 sql (var ediDocuments =) 中返回值——它不应该工作,因为它不是 SELECT sql 查询。所以你应该决定是否要更新选择某些行的行
  • 谁能指导我如何在 sql 参数中提及可为空的日期时间类型,新的 SqlParameter { ParameterName = "startDate", DbType = System.Data.DbType.DateTime, Value = startDate },
【解决方案2】:
  foreach (var senderId in senderIdList)
  {
    using (var context = new BSoftWEDIIContext())
    {
      var ediDocuments = context.EDIDocuments.SqlQuery($"Update EDIDocument SET IsIgnored=1 from EDIDocument edi  inner JOIN  FileDetails files on edi.FileDetailsId = files.Id where edi.IsDeleted = 0 and  edi.SenderID={senderId} and edi.DocumentTypeID != 3 and edi.DocumentTypeID != 5 and edi.DocumentTypeID != 2 and edi.IsIgnored = 0 and files.IsDeleted = 0" );
    }

  }

但是这种方法有可能进行 SQL 注入。

【讨论】:

  • 它没有抛出异常但仍然没有在数据库中更新
  • @Achu_L,试试context.Database.ExecuteSqlCommand(commandText);
【解决方案3】:

首先你应该知道DbSet.SqlQuery()方法主要用于执行SELECT语句,它根据相应的实体类型返回结果集,即DbSet名称。如果要执行UPDATE 命令之类的操作查询,则应使用Database.ExecuteSqlCommand()SqlParameter[] 数组作为参数,如下例所示:

string rawQuery = @"Update EDIDocument SET IsIgnored = 1 From EDIDocument AS edi  
                 INNER JOIN FileDetails AS files on edi.FileDetailsId = files.Id 
                 where edi.IsDeleted = 0 and edi.SenderID = @senderId 
                 and edi.DocumentTypeID <> 3 and edi.DocumentTypeID <> 5 
                 and edi.DocumentTypeID <> 2 and edi.IsIgnored = 0 and files.IsDeleted = 0";

using (var context = new BSoftWEDIIContext())
{
     foreach (var senderId in senderIdList)
     {
         var queryParams = new List<SqlParameter>();
         queryParams.Add(new SqlParameter("@senderId", senderId));

         var ediDocuments = context.Database.ExecuteSqlCommand(rawQuery, queryParams.ToArray());
     }
}

注意:

DbSet.SqlQuery()Database.ExecuteSqlCommand() 方法的第二个参数都使用object[] 数组,因此您需要将参数传递到数组中,而不是直接使用它们。

参考:

Execute Raw SQL Queries Using Entity Framework

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多