无法映射属性“PropertyName”,因为它的类型为“List<decimal>”

问题描述 投票:0回答:5

当我尝试使用 EntityFramework Core 创建数据库时遇到此问题:

无法映射属性“Rating.RatingScores”,因为它的类型为“List”,该类型不是受支持的基元类型或有效的实体类型。显式映射此属性,或者使用“[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);
    }
}
c# entity-framework-core
5个回答
19
投票

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

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

然后评级属性将如下所示:

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

但是,如果每个评级都有一个评级分数,则您的财产不应该是一个集合。

public RatingScore MyRatingScore { get; Set; }

6
投票

当你确实需要放

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

完成!!它应该可以工作


2
投票
对于EntityFramework Core。该解决方案将帮助您在数据库中保存正确的数据,并且每当结果从数据库返回时,它都会转换为列表。

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

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

无法映射属性“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(); }
总结:当你重写一个方法时,不要忘记调用基本方法。很多时候基本方法没有做太多事情,所以我们忽略它们。但有时他们会这样做。所以总是调用基本方法。


0
投票
在我的例子中,我实际上有表格,但无论出于何种原因,有以下行(默认

标量值!)

modelBuilder.Entity<Invoice>(entity => { // ... entity.Property(e => e.InvoicePositions).HasDefaultValueSql("'0'");` }
删除错误的线路解决了问题。

© www.soinside.com 2019 - 2024. All rights reserved.