Обновить поле в базе данных с помощью Raw SQL?

Мне нужно обновить поле IsIgnored на основе senderId, когда я проверяю, где условие, оно не идентифицирует 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));

person Achu_L    schedule 11.12.2018    source источник
comment
Что такое senderId? Если это параметр, вам нужно использовать префикс @ и использовать SqlParameter; в противном случае укажите псевдоним таблицы, чтобы отличить его от того же имени столбца в других таблицах, например. files.senderId.   -  person Tetsuya Yamamoto    schedule 11.12.2018


Ответы (3)


Вам нужно добавить параметр 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
                            });
                    }
                }
person Maxim Saltanov    schedule 11.12.2018
comment
edi.SenderID=@senderId - вы уверены, что добавили символ @ в параметр в запросе sql? - person Maxim Saltanov; 11.12.2018
comment
добавлено, теперь это отображается как Средство чтения данных несовместимо с указанным «BSoftWEDII.Data.EDIDocument». Член типа «Id» не имеет соответствующего столбца в средстве чтения данных с таким же именем. - person Achu_L; 11.12.2018
comment
Попробуйте использовать ExecuteSqlCommand вместо SqlQuery. Также проверьте типы и наличие полей edi.SenderID, files.Id в базе данных - person Maxim Saltanov; 11.12.2018
comment
Примечание: вы не можете возвращать значения в вашем sql (var ediDocuments =) - это не должно работать, потому что это не SELECT sql-запрос. поэтому вы должны решить, хотите ли вы обновить строки или выбрать некоторые строки - person Maxim Saltanov; 11.12.2018
comment
может ли кто-нибудь указать мне, как указать тип даты и времени с нулевым значением в параметре sql, новый SqlParameter {ParameterName = startDate, DbType = System.Data.DbType.DateTime, Value = startDate}, - person Achu_L; 11.12.2018
comment
Я надеюсь, что эта статья поможет - stackoverflow.com /вопросы/7497786/ - person Maxim Saltanov; 11.12.2018

  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-инъекций.

person Denis Derkach    schedule 11.12.2018
comment
Он не генерирует исключение, но все еще не обновляется в базе данных. - person Achu_L; 11.12.2018
comment
@Achu_L, попробуй context.Database.ExecuteSqlCommand(commandText); - person Denis Derkach; 11.12.2018

Первое, что вы должны знать, это 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[], поэтому вам нужно передавать параметры в массив, а не использовать их напрямую.

Ссылка:

Выполнение необработанных запросов SQL с помощью Entity Framework

person Tetsuya Yamamoto    schedule 11.12.2018