2016-12-08 2 views
0

У меня есть устаревшая база данных, в которой хранятся комментарии пользователей (и немало других текстовых полей) как тип данных blob, который я не могу изменить.Entity Framework Core 1.1.0 Преобразование типа данных

Я пишу уровень доступа к данным, который должен всегда преобразовывать данные в string, когда он извлекается из базы данных, и конвертирует его обратно в blob при сохранении.

Инструмент для строительных лесов EF сгенерировал свойства типа byte[] для этих объектов.

public byte[] Comment { get; set; } 

Я заметил, что если я просто изменить объектный тип собственности для string это на самом деле сохранить данные правильно, но загрузка результатов данных в виде ошибки литья:

Unable to cast object of type 'System.Byte[]' to type 'System.String'.

(Интересно, что версия 1.0.0 не бросить эту ошибку, загрузка и сохранение работали нормально.)

Мой вопрос ... есть ли способ настройки EF ядра т o автоматически конвертировать эти данные в строку, когда я получаю ее из базы данных и обратно до blob, когда она будет сохранена обратно? Или мне нужно написать целую кучу частных геттеров и сеттеров, чтобы сделать эту манипуляцию?

+0

'byte []' - совершенно другой тип данных, чем 'string'. Преобразование 'byte []' в 'string' зависит от кодировки, ... EF не может сделать это для вас.Лучше всего оставить его как 'byte []' и написать getter, который возвращает вам строковое представление, подобное 'public string MyString {get {return Encoding.UTF8.GetString (MyBytes); }} ' –

+1

Я думаю, что ваш лучший выбор - это свойства приятеля, пока https://github.com/aspnet/EntityFramework/issues/242 не достигнет успеха. –

ответ

4

В дополнении к моему комментарию на вашем answere, если вы не хотите, чтобы добавить получателей и установщик и хотим иметь чистый код, вы могли бы также работать с надставками-методами:

public static class Extensions 
{ 
    public static byte[] GetBytes(this string @this, System.Text.Encoding encoding = null) 
    { 
     return (encoding??Encoding.UTF8).GetBytes(@this); 
    } 

    public static string GetString(this byte[] @this, System.Text.Encoding encoding = null) 
    { 
     return (encoding??Encoding.UTF8).GetString(@this); 
    } 
} 

вы можете работать с ними как это так:

myentity.Comment = "my comment".GetBytes(); 
string comment = myentity.Comment.GetString(); 

ухода возьмет по умолчанию значение в коде, то есть UTF8, вы можете изменить его в кодировку вы хотите использовать, или введите другую кодировку, как

byte[] myBytes = "my comment".GetBytes(Encoding.ASCII); 

вашей победы: вы не должны указывать геттер/сеттер в каждое свойство с использованием byte[]

+1

Спасибо за это решение. Хотя оба текущих ответа будут эффективно помогать решить эту проблему, я выбрал это как принятый ответ исключительно потому, что он наилучшим образом подходит для моего конкретного требования. Надеемся, что команда EF Core в ближайшее время реализует этот http://github.com/aspnet/EntityFramework/issues/242. – Bandito

2

Преобразование byte[] в stringвсегда требует Encoding. Поскольку EF не знает, какую кодировку использовать, такое автоматическое преобразование невозможно.

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

partial class MyEntity 
{ 
    private string m_commentText = null; 
    public string CommentText 
    { 
     get { 
      if ((m_commentText == null) && (Comment != null)) { 
       m_commentText = Encoding.UTF8.GetString(Comment);  
      } 
      return m_commentText; 
     } 
     set { 
      m_commentText = value; 
      if (value != null) { 
       Comment = Encoding.UTF8.GetBytes(value); 
      } 
      else { 
       Comment = null; 
      } 
     } 
    } 
} 

Это решение Хранит текст в поле защитника, чтобы избежать нескольких преобразований от byte[] до string. Если вам нужно Comment свойства оставаться общедоступными, необходимо удалить поле покровителя, чтобы избежать несоответствия данных:

partial class MyEntity 
{ 
    public string CommentText 
    { 
     get { 
      if (Comment != null) { 
       return Encoding.UTF8.GetString(Comment);  
      } 
      else { 
       return null; 
      } 
     } 
     set { 
      if (value != null) { 
       Comment = Encoding.UTF8.GetBytes(value); 
      } 
      else { 
       Comment = null; 
      } 
     } 
    } 
} 
+0

возможно указать 'byte [] Комментарий'-property в сущности, чтобы сделать его немного яснее –

+0

Да, я бы хотел, но эта часть автогенератора. Нет смысла указывать автогенерируемое свойство. Вот почему включается 'partial'. – Sefe

+0

А я вижу, так что, возможно, добавьте к своему ответу, что сгенерированный класс также должен быть «partial». Или генерируется всегда частичный класс? Я не знаю, что генерирует инструмент EF scaffolding;) –

Смежные вопросы