Ger Hayden Ответов: 1

Ядро Entity framework: входная строка была не в правильном формате


Я становлюсь туманным
input string was not in a correct format
и я вижу, что это было задано раньше, но я попытался получить тип переменной по порядку, но безрезультатно. Я был бы признателен за помощь.

Вот мои сообщения в журнале:
WARN  07:05:02 The LINQ expression 'where (((Convert([e].p_Expiry_ID, Int32) == Convert(__tmpExpiryID_0, Int32)) AndAlso ([e].p_Valid_From <= DateTime.Now)) 
AndAlso ((ToDateTime([e].p_strValid_To) >= DateTime.Now) OrElse ([e].p_strValid_To == null)))' could not be translated and will be evaluated locally.


Int32 здесь интересен, потому что мои определения-Int16, а затем идет исключение:
SELECT `e`.`Expiry_ID`, `e`.`Valid_From`, `e`.`Day`, `e`.`Description`, `e`.`Expiry_Type`, `e`.`Export`, `e`.`Fixed_Interval_ID`, `e`.`Number_Interval_Units`, `e`.`Unit_ID`, `e`.`Valid_To`
FROM `ExpiryMaster` AS `e`
ORDER BY `e`.`Valid_From`
ERROR 07:05:02 An exception occurred in the database while iterating the results of a query for context type 'VT_OnlineCore.Models.ApplicationDbContext'.
System.InvalidOperationException: An exception occurred while reading a database value. See the inner exception for more information. ---> System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   at MySql.Data.MySqlClient.MySqlDataReader.GetInt32(Int32 i)
   at lambda_method(Closure , DbDataReader )
   --- End of inner exception stack trace ---
   at Microsoft.EntityFrameworkCore.Metadata.Internal.EntityMaterializerSource.ThrowReadValueException[TValue](Exception exception, Object value, IPropertyBase property)
   at lambda_method(Closure , DbDataReader )
   at Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.BufferlessMoveNext(Boolean buffer)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found)
   at lambda_method(Closure , QueryContext )
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass17_1`1.<CompileQueryCore>b__0(QueryContext qc)


Теперь вот код, который делает вызов. Поскольку переменная параметра является nullable я попытался переместить ее в фиксированный тип заранее:

CExpiryMasterBase ExpiryRecord = new CExpiryMasterBase();
  Int16 tmpExpiryID = (Int16)workingTicket.ExpiryID;
   ExpiryRecord = repositoryExpiryMaster.ExpiryMaster
                               .Where(e => e.p_Expiry_ID == tmpExpiryID
                 && e.p_Valid_From <= DateTime.Now
                  && ((Convert.ToDateTime(e.p_strValid_To) >= DateTime.Now) || (e.p_strValid_To == null)))
                  .OrderBy(e => e.p_Valid_From)
                  .FirstOrDefault();


Это свойство используется:

   public Int16 p_Export
    {
        get
        {
            return m_Export;
        }
        set
        {
            m_Export = value;
        }
    }
private Int16   m_Expiry_ID;


Это определение поля:
Expiry_ID	tinyint(2)	NO	PRI	


База данных MySQL

Что я уже пробовал:

Удаление действительно С и действительно получить из запроса, используя временной области, чтобы избежать необходимости в поле значения NULL в запросе.

Я также попробовал элементарный прямой SQL запрос и получил тот же результат ошибки:
IQueryable<CExpiryMasterBase> data = context.ExpiryMaster
                               .FromSql(@"SELECT * FROM ExpiryMaster
                                   WHERE Expiry_ID = 1
                                   ");

F-ES Sitecore

Ваш код;

Преобразовать.ToDateTime(например, p_strValid_To)

вероятно, это вызывает эту ошибку, потому что e.p_strValid_To не может быть преобразован в дату и время. У вас может возникнуть еще одна проблема, если ExpiryMaster является сущностью entity framework, поскольку ваш "Where" должен быть преобразован в SQL, и если базовый поставщик MySQL не может преобразовать "Convert.ToDateTime" в SQL он не сможет выполнить ваш запрос. Если p_strValid_To содержит информацию о дате, то убедитесь, что это формат даты, а не строка\varchar, поэтому он не нуждается в преобразовании. EF не может спасти вас от плохого дизайна базы данных.

Ger Hayden

Эта конкретная неприятность возникла в 2005 году, когда было невозможно (или я не знал, как) иметь нулевое значение в поле MySQL Datetime и с тех пор продолжалась. Из того, что я вижу, все еще есть некоторые проблемы вокруг того же самого. Тем временем я вычеркну условия даты и жестко закодирую идентификатор истечения срока действия до 1 затем посмотрю что произойдет и доложу об этом

F-ES Sitecore

В подобных ситуациях люди обычно использовали минимальное значение для поля как "null".

Ger Hayden

Я только что опубликовал обходной путь

Ger Hayden

Кое-что я рассмотрю в будущем, но пока это не имеет отношения к рассматриваемой проблеме, потому что она сохраняется даже тогда, когда поля даты удаляются из запроса. Это один из многих подобных запросов, где все остальные работают так, как ожидалось. Это тонкое различие, которое еще предстоит обнаружить.

Richard Deeming

Похоже, что у вас есть строковый столбец в базе данных, сопоставленный с нестроковым свойством в вашей модели, и по крайней мере одна из строк, которые вы пытаетесь загрузить, имеет недопустимое значение в этом столбце.

Ger Hayden

Проверил это. С тех пор как я закончил этот день, мне пришло в голову, что это мой первый доступ к таблице с перечисляемым типом данных. Вот это беда! Я нашел кое-что, что может работать на Stackoverflow https://stackoverflow.com/questions/44262314/how-can-i-make-ef-core-database-first-use-enums/48237275

Если это не удастся, то мне, возможно, придется стереть пыль с моего модуля обработчика данных для этой таблицы, которая является частью набора, который обслуживал часть winform системы с тех пор .Чистая миграция в 08 году. Они были отложены только для того, чтобы освободить мне место для изучения EF core.

1 Ответов

Рейтинг:
6

Ger Hayden

Предложение stackoverflow было неудачным, возможно, потому, что перечисления в моем решении находятся в пользовательских типах дальше вверх по течению от свойства, которое сопоставляется со столбцом в таблице.

Я обошел его, запросив базу данных вне кода Entity Framework с помощью:

MySqlCommand cmd = new MySqlCommand();
 cmd.Connection = m_Connection; // Passed in from the controller
 cmd.CommandType = CommandType.Text;

            cmd.CommandText =
                 String.Format(@"select Expiry_Type,
                                Unit_ID,
                    Fixed_Interval_ID,
                    Day,
                    Number_Interval_Units
                                from ExpiryMaster
                    where Expiry_ID = {0}
                    and valid_from <= '{1}'
                    and(valid_to >= '{1}' or valid_to is NULL)",
                    arg_Param_ID, m_OrigDate);

MySqlDataReader reader = cmd.ExecuteReader();

while (reader.Read())
 {
    // Process the result
 }