Entity Framework Core 1.1.0 Data type conversion

c# entity-framework-core

Question

I have a legacy database that stores user comments (and quite a few other text fields) as blob datatype, which I cannot change.

I am writing a data access layer that will need to always convert the data to a string when it is retrieved from the database, and convert it back to blob when saving.

The EF scaffolding tool generated properties as byte[] datatype for these entities.

public byte[] Comment { get; set; }

I noticed that if I simply change the entity property type to string it actually does save the data correctly, but loading the data results in a casting error:

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

(Interestingly, version 1.0.0 did not throw this error, loading and saving worked ok.)

My question is... Is there a way of configuring EF core to automatically convert this data to string when I retrieve it from the database and back to blob when it gets saved back? Or will I need to write a whole bunch of private getters and setters to do this manipulation?

1
0
12/8/2016 6:08:01 PM

Accepted Answer

In addition for my comment on your answere, if you don't want to add getters and setters and want to have clean code, you could also work with extension-methods:

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);
    }
}

you can work with them both this way:

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

take care of the default-value in the code, that is UTF8, you can change it to the encoding you want to use, or enter another encoding like

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

your win: you don't have to specify a getter/setter to each property using byte[]

5
12/8/2016 1:00:44 PM

Popular Answer

Converting the byte[] into a string always requires an Encoding. Since EF does not know which encoding to use, such an automatic conversion is not possible.

What you can do though is to mark your Comment property as private and to create a wrapper property that converts the value to a string with an Encoding of your choice:

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;
            }
        }
    }
}

This solution stores the text in a backer field to avoid multiple conversions from byte[] to string. If you need the Comment property to stay public, you need to remove the backer field to avoid data inconsistency:

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;
            }
        }
    }
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow