4

I have an object with an array property that I want to persist in the database as a delimited string. How to I Map that property to the field in the database and vice versus?

public class User() {
  public int Id { get; set; }
  public string[] Roles { get; set; }
}

Incomplete Config Class:

public class UserConfig : EntityTypeConfiguration<User> {
  public UserConfig() {
    this.Property(u => u.Roles).__???__
    this.Map(u => u.Properties<string[]>(r => r.Roles).__???__))
      .HasColumnName("roles");
  }
}

For this example the "Roles" property would be converted to "roleA,roleB,roleC" when going to the database and then transformed back to an array when read from the database. Is there an on data mapping event somewhere?

jedatu
  • 4,053
  • 6
  • 48
  • 60

2 Answers2

6

You need an additional property that wraps and converts the String into a String[].

public class User() {
  public int Id { get; set; }
  public string Roles { get; set; }
  public string[] RolesArray 
  { 
    get
    {
      return Roles.Split(',').ToArray();
    }
    set
    {
      Roles = String.Join(',', value);
    }
  }
}

The preferred solution would of course be to add a new table to your database called Role, and have a one-many relationship so that a User has many Roles. This will allow EF to manage everything for you, and means your data is stored coherently and accessibly. Comma delimited strings are not particularly pleasant to work with and shouldn't be stored in databases.

Kirk Broadhurst
  • 27,836
  • 16
  • 104
  • 169
  • "shouldn't be stored in databases" Why? – Matt Kocaj Sep 21 '16 at 01:41
  • 1
    @cottsak I guess this five and a half year old answer might be out of date, but a *relational* database would prefer that you store an array of comma delimited items in a denormalized way - i.e. as a collection of rows where each row contains only one item. Today many databases natively support arrays and collections, but that isn't standard SQL and won't be transferable. – Kirk Broadhurst Sep 21 '16 at 01:48
1

You have to provide additional property which will implement conversion logic between string and array. You will map that property and ignore Roles property.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670