【问题标题】:No suitable constructor found for entity type 'Uri'.没有为实体类型“Uri”找到合适的构造函数。
【发布时间】:2019-03-28 14:03:48
【问题描述】:

我有这个模型:

public class Book
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Uri Link { get; set; }
}

我使用以下代码将其添加到fluent-api

 builder.Entity<Book>(entity => {
     entity.HasKey(b => b.Id);
 });

当我运行这个时:

add-migration InitialMigration -context MyAppContext

然后我得到:

没有为实体类型“Uri”找到合适的构造函数。以下参数无法绑定到实体的属性:'uriString'、'uriString'、'dontEscape'、'baseUri'、'relativeUri'、'dontEscape'、'uriString'、'uriKind'、'baseUri'、' relativeUri'、'serializationInfo'、'streamingContext'、'baseUri'、'relativeUri'、'flags'、'uriParser'、'uri'。

【问题讨论】:

  • 由于 Uri 不是平面类型,它必须映射到另一个表,其列与其属性匹配。但是,要让 EF 能够进行映射(尤其是具体化值),所有映射的属性都必须有一个 setter,并且实体类型必须有一个无参数的构造函数,而 Uri 则不是这样。
  • 那么解决办法是什么?
  • 要么创建一个可以跟踪 Uri (必要)属性的 POCO 类,要么使用可以转换为并适合单个列的类型。
  • POCO 到底是什么意思?

标签: asp.net entity-framework asp.net-core


【解决方案1】:

您不能将Uri 直接保存到数据库中,因为没有与之相关的 SQL 类型。您需要改用字符串。如果您正在使用视图模型(应该如此),您的视图模型可以具有Uri,然后您只需在映射到实际实体类型期间获取字符串表示。

您还可以简单地利用 EF Core 的值转换(在 2.1+ 中可用)。有关更多详细信息,请参阅docs。本质上,在您流畅的配置中:

.HasConversion(
    v => v.ToString(),
    v => new Uri(v));

【讨论】:

    【解决方案2】:

    可以将值转换添加到您的DbContext 以转换读取或写入数据库时​​使用的类型。这是通过覆盖OnModelCreating 方法来完成的。

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder
            .Entity<Book>()
            .Property(e => e.Link)
            .HasConversion(v => v.ToString(), v => new Uri(v));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      • 2021-08-15
      相关资源
      最近更新 更多