How to persist a list of strings with Entity Framework Core?

.net-core c# entity-framework entity-framework-core

Question

Let us suppose that we have one class which looks like the following:

public class Entity
{
    public IList<string> SomeListOfValues { get; set; }

    // Other code
}

Now, suppose we want to persist this using EF Core Code First and that we are using a RDMBS like SQL Server.

One possible approach is obviously to create a wraper class Wraper which wraps the string:

public class Wraper
{
    public int Id { get; set; }

    public string Value { get; set; }
}

And to refactor the class so that it now depends on a list of Wraper objects. In that case EF would generate a table for Entity, a table for Wraper and stablish a "one-to-many" relation: for each entity there is a bunch of wrapers.

Although this works, I don't quite like the approach because we are changing a very simple model because of persistence concerns. Indeed, thinking just about the domain model, and the code, without the persistence, the Wraper class is quite meaningless there.

Is there any other way persist one entity with a list of strings to a RDBMS using EF Core Code First other than creating a wraper class? Of course, in the end the same thing must be done: another table must be created to hold the strings and a "one-to-many" relationship must be in place. I just want to do this with EF Core without needing to code the wraper class in the domain model.

1
20
5/22/2016 4:14:24 AM

Popular Answer

This can be achieved in a much more simple way starting with Entity Framework Core 2.1. EF now supports Value Conversions to specifically address scenarios like this where a property needs to be mapped to a different type for storage.

To persist a collection of strings, you could setup your DbContext in the following way:

protected override void OnModelCreating(ModelBuilder builder)
{
    var splitStringConverter = new ValueConverter<IEnumerable<string>, string>(v => string.Join(";", v), v => v.Split(new[] { ';' }));
    builder.Entity<Entity>().Property(nameof(Entity.SomeListOfValues)).HasConversion(splitStringConverter);
} 

Note that this solution does not litter your business class with DB concerns.

Needless to say that this solution, one would have to make sure that the strings cannot contains the delimiter. But of course, any custom logic could be used to make the conversion (e.g. conversion from/to JSON).

Another interesting fact is that null values are not passed into the conversion routine but rather handled by the framework itself. So one does not need to worry about null checks inside the conversion routine. However, the whole property becomes null if the database contains a NULL value.

17
11/8/2019 1:59:41 PM


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