【问题标题】:The property 'PropertyName' could not be mapped, because it is of type 'List<decimal>'无法映射属性“PropertyName”,因为它的类型为“List<decimal>”
【发布时间】:2019-01-10 13:25:36
【问题描述】:

我在尝试使用 EntityFramework Core 创建数据库时遇到了这个问题:

无法映射属性“Rating.RatingScores”,因为它属于“列表”类型,不是受支持的原始类型或有效的实体类型。显式映射此属性,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略它。

这是课程:

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

【问题讨论】:

  • 如错误消息所示,尝试使用[NotMapped],因为这看起来不像您存储在数据库中的内容。如果要将值存储在数据库中,请为新表创建一个新类,然后进行相应的映射 (stackoverflow.com/a/30202171/1073631)。

标签: c# entity-framework-core


【解决方案1】:

如果 Rating 类有多个 RatingScores,您有一对多的关系,并且 RatingScores 属性需要自己的表,因此您需要创建一个新类。

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

那么 Rating 属性将如下所示:

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

但是,如果每个 Rating 都有一个 RatingScore,则您的属性不应是一个集合。

public RatingScore MyRatingScore { get; Set; }

【讨论】:

    【解决方案2】:

    当你确实需要输入multiple values in single column时可以使用下面的方式

    假设您只想为下面的类创建一个表

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

    首先创建一个converter,它将控制.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)); ; 
                
            }
        }
    

    DbContext 应该有下面的方法

     protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
             .....
    
            var IntValueConverter = new IntListToStringValueConverter();
    
            modelBuilder
                .Entity<SomeClass>()
                .Property(e => e.Values)//Property
                .HasConversion(IntValueConverter);
    
        }
    

    完成!! IT 应该可以工作了

    【讨论】:

    • 谢谢!这就像一个魅力。它还抱怨了一个比较器,所以代码最后看起来像这样:a.Property(e =&gt; e.Time).HasConversion(listToStringValueConverter).Metadata.SetValueComparer(valueComparer);
    【解决方案3】:

    好的。这是我的错误,我刚刚发现问题所在。

    无法映射属性“LogEntry.Timestamp”,因为它属于“Instant”类型,它不是受支持的原始类型或有效的实体类型。显式映射此属性,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略它。

    其实它想说的很清楚。

    我已经覆盖了 OnModelCreating,但我错过了一件小事。

    这是我的 dbcontext 类。

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

    请注意,我已经注释掉了基本方法调用。这就是造成问题的原因。

    被覆盖的方法应该如下。

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

    总结:当你重写一个方法时不要忘记调用基方法。很多时候,基本方法没有多大作用,所以我们忽略它们。但有时他们会这样做。所以总是调用基方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-27
      • 2021-07-04
      • 1970-01-01
      • 2018-02-15
      • 1970-01-01
      • 2021-08-15
      • 2022-10-12
      相关资源
      最近更新 更多