我有一个遗留数据库,它将用户注释(以及其他一些文本字段)存储为blob
数据类型,我无法更改。
我正在编写一个数据访问层,当从数据库中检索数据时,需要始终将数据转换为string
,并在保存时将其转换回blob
。
EF脚手架工具为这些实体生成了byte[]
数据类型的属性。
public byte[] Comment { get; set; }
我注意到,如果我只是将实体属性类型更改为string
,它实际上会正确保存数据,但加载数据会导致转换错误:
无法转换类型为#System; Byy []'的对象输入' System.String'。
(有趣的是,版本1.0.0没有抛出此错误,加载和保存工作正常。)
我的问题是...... 有没有办法配置EF核心,以便在我从数据库中检索数据时自动将此数据转换为字符串,并在保存时返回blob
背部?或者我是否需要编写一大堆私有的getter和setter来进行这种操作?
答案 0 :(得分:5)
除了我对你的回答的评论,如果你不想添加getter和setter并希望拥有干净的代码,你也可以使用扩展方法:
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 :(得分:2)
将byte[]
转换为string
始终需要Encoding
。由于EF不知道使用哪种编码,因此无法进行这种自动转换。
你可以做的是将Comment属性标记为私有,并创建一个包装属性,将值转换为您选择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;
}
}
}
}