在 ef core 2.0 中具有复杂类型的列类型

Has column type of complex type in ef core 2.0

我想使用 fluent api 更改 属性 的列类型,但出现错误

表达式 'x => x.NestedProp.Prop1' 不是有效的 属性 表达式。该表达式应表示 属性 访问:'t => t.MyProperty'.

拜托,我不想使用 DataAnnotations

这是我的代码 (类):

public class Class1 {
     public int Id { get; set; }
     public NestedProp NestedProp { get; set; } = new NestedProp();
}

public class NestedProp {
     public decimal Prop1 { get; set; }
}

OnModelCreating:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Class1>(e =>
            {
                e.OwnsOne(t => t.NestedProp);
                e.Property(p => p.NestedProp.Prop1).HasColumnType("NUMERIC(38, 16)");
            });
}

请尝试以下内容并注意 class NestedProp 中的 Id 属性。 EF (Core) 在每个模型中都需要一个主键,否则将无法工作。

型号

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

     public virtual NestedProp NestedProp { get; set; } = new NestedProp();
}

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

     public decimal Prop1 { get; set; }
}

OnModelCreating

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var class1Entity = modelBuilder.Entity<Class1>();
    class1Entity.HasOne(p => p.NestedProp);

    var nestedPropEntity = modelBuilder.Entity<NestedProp>();
    nestedPropEntity.Property(p => p.Prop1)
        .HasColumnType("NUMERIC(38, 16)"); // maybe decimal instead of numeric?
}

在这里您会发现更多 explanation。 您必须为每个模型定义配置。

我建议使用 IEntityTypeConfiguration<T> 而不是在 OnModelCreating 中配置所有内容。

关于在 EF Core 中使用 Fluent API 的精彩介绍,您会发现 here or here

编辑:

上面的解决方案将创建两个表,因为它实现了两种自己的数据类型。不是有问题的在列中询问复杂类型。因此,我也会为这个解决方案提供建议。这种拥有的类型映射可以通过 entity.OwnsOne(...) 方法实现。也可以像本文中提到的那样拆分 MS doc article. In this article 你也会发现如何明确配置它。

这里是你的代码和流利的例子API:

型号

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

     public virtual NestedProp NestedProp { get; set; } = new NestedProp();
}

public class NestedProp
{
     public decimal Prop1 { get; set; }
}

OnModelCreating

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    var class1Entity = modelBuilder.Entity<Class1>();
    class1Entity.OwnsOne(
            class1 => class1.NestedProp,
            nestedProp =>
            {
                nestedProp.Property(p => p.NestedProp)
                      .HasColumnType("NUMERIC(38, 16)")
                      .HasColumnName("NestedPropValue"); // here you could add a custom name like I did or remove it and you get a generated one
            });
}