0

I am trying to implement a localization logic using json to store localized string in the database using Entity Framework, but I need help completing the object.

Here's my localized field

[ComplexType]
    public class MultiLanguageField : Dictionary<string, string>
    {
        public void AddRange(Dictionary<string, string> collection)
        {
            foreach (var item in collection)
            {
                this.Add(item.Key, item.Value);
            }
        }       

        [Column("Name")]
        public string Serialized
        {
            get { return JsonConvert.SerializeObject(this); }
            private set
            {
                if(string.IsNullOrEmpty(value))
                {
                    Clear();
                    return;
                }

                var items = JsonConvert.DeserializeObject<MultiLanguageField>(value);
                Clear();
                AddRange(items);
            }
        }
    }

Then I just declare the property in an object like this.

public MultiLanguageField LocalizedField { get; set; }

I want to be able to replace the Column attribute over the Serialized method so the database field takes the name of the declaring property (LocalizedField in this case).

I looked at reflection, but can't manage to get the name of the declaring property.

Any help appreciated. If you know a better way to manage localization in database with Entity Framework, I welcome your input!

Thx

EDIT

I'll try to clarify. By default, the name of the column in the database would be LocalizedField_Serialized (PropertyNameOnParent_PropertyNameOnComplexType).

How can I tell Entity Framework to only take the PropertyNameOnParent instead of appending the "Serialized" property.

This looks like a start. I'll look at it later.

Entity Framework complex type's columns naming convention

Bruno
  • 137
  • 1
  • 10

1 Answers1

1

What I was actually looking for (without knowing it) was a way to override the default naming convention.

I ended up using this solution

By adding a Convention to the modelBuilder, I was able to overwrite the name that was given to the Serialized property like this.

class MultiLanguageStringNamingConvention : IStoreModelConvention<EdmProperty>
    {
        public void Apply(EdmProperty property, DbModel model)
        {
            string propertyName = string.Format("_{0}", nameof(MultiLanguageString.MultiLanguageString_Serialized));
            if (property.TypeName.ToLower() == "nvarchar(max)" && property.Name.EndsWith(propertyName))
            {
                property.Name = property.Name.Replace(propertyName, "");
            }
        }
    }

Then you add it to the modelBuilder.

modelBuilder.Conventions.Add(new MultiLanguageStringNamingConvention());

In the end, this solution gives me the "LocalizedField" column name I was looking for in the first place.

This allows me to use the MultiLanguageString for any localized field. It ends up as a json string in the database and is pretty easy to use.

public class Movie
{
    public MultiLanguageString Title { get; set; }
}

var movie = new Movie
{
    Title = new MultiLanguageString
    {
        { "en-CA", "Eternal Sunshine of the Spotless Mind" },
        { "fr-CA", "Du soleil plein la tĂȘte" }
    }
};

var englishTitle = movie.Title["en-CA"];
Bruno
  • 137
  • 1
  • 10