'The property 'PropertyName' could not be mapped, because it is of type 'List<decimal>'

I got this problem when I try to create the database with EntityFramework Core:

The property 'Rating.RatingScores' could not be mapped, because it is of type 'List' which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

Here is the class:

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

    public List<decimal> RatingScores { get; set; }

    public decimal Score
    {
        set => Score = value;
        get => Math.Round(RatingScores.Sum() / RatingScores.Count, 1);
    }
}


Solution 1:[1]

If the Rating class has multiple RatingScores you have a one-to-many relationship and the RatingScores property needs its own table, you therefore need to create a new class.

Class RatingScore 
{
  public int Id { get; set; }
  public decimal RtSc { get; set; }
}

Then the Rating property will look like this:

public List<RatingScore> MyRatingScores { get; set; }

However if each Rating has one RatingScore, your property should not be a collection.

public RatingScore MyRatingScore { get; Set; }

Solution 2:[2]

When you really need to put multiple values in single column can use below way

Let's say you want to create only one table for below class

public class SomeClass
{
    public Guid ID { get; set; }
    public IEnumerable<int> Values { get; set; }
}

First create a converter, which will control .net values to db values and vice versa

    using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
 
    public class IntListToStringValueConverter : ValueConverter<IEnumerable<int>, string>
    {
        public IntListToStringValueConverter() : base(le => ListToString(le), (s => StringToList(s)))
        {

        }
        public static string ListToString(IEnumerable<int> value)
        {
            if (value==null || value.Count()==0)
            {
                return null;
            }
 
            return value.Join(',');
        }

        public static IEnumerable<int> StringToList(string value)
        {  
            if (value==null || value==string.Empty)
            {
                return null;
            }

            return value.Split(',').Select(i => Convert.ToInt32(i)); ; 
            
        }
    }

And DbContext should have below method

 protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
         .....

        var IntValueConverter = new IntListToStringValueConverter();

        modelBuilder
            .Entity<SomeClass>()
            .Property(e => e.Values)//Property
            .HasConversion(IntValueConverter);

    }

Done!! IT should work

Solution 3:[3]

Ok. Here is my error and I just found what the problem is.

The property 'LogEntry.Timestamp' could not be mapped because it is of type 'Instant', which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

Actually its fairly clear what it is trying to say.

I have overridden OnModelCreating but I missed a trivial thing.

Here is my dbcontext class.

public class ExtendedElsaMigrationsDbContext : SqlServerContext
{
    public ExtendedElsaMigrationsDbContext(DbContextOptions options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // I should not comment out this base method call.
        // base.OnModelCreating(modelBuilder);
        // modelBuilder.Entity<User>();

        modelBuilder.ConfigureExtendedElsaDbContext();
    }
} 

Note that I had commented out the base method call. And that is what is causing the problem.

The overridden method should be as follows.

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        //    //modelBuilder.Entity<User>();

        modelBuilder.ConfigureExtendedElsaDbContext();
    }

Summary: Don't forget to call the base method when you are overriding a method. Many times base method don't do much, so we ignore them. But some times they do. So always call the base methods.

Solution 4:[4]

For EntityFramework Core. This solution will help you to save proper data in DB as well as, whenever the result comes back from DB, it will convert to List.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<WebhookSubscription>()
      .Property(p => p.Webhooks)
      .HasConversion(v => JsonConvert.SerializeObject(v),
                     v => JsonConvert.DeserializeObject<List<string>>(v));
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Matt Fricker
Solution 2
Solution 3 VivekDev
Solution 4 KushalSeth