Has column type of complex type in ef core 2.0

2019-07-11 02:49发布

I want to change column type of property using fluent api, but i have an error

The expression 'x => x.NestedProp.Prop1' is not a valid property expression. The expression should represent a property access: 't => t.MyProperty'.

please, i dont want to use DataAnnotations

Here is my code (Classes):

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

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

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

1条回答
时光不老,我们不散
2楼-- · 2019-07-11 03:11

Please give the following a try and pay attention to the Id property in your class NestedProp. EF (Core) needs in every model a primary key, otherwise it will not work.

Models

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?
}

Here you will find some more explanation. You have to define the configuration for each model.

I recommend to use IEntityTypeConfiguration<T> instead of configure everything in OnModelCreating.

A nice introduction for using the Fluent API in EF Core would you find here or here.

EDIT:

The Solution above will create two tables, because it implements two own data types. Not the in question asked complex type in on column. Therefore I will give advise for this solution too. This owned type mapping is realizable via entity.OwnsOne(...) method. It is also possible to split in like mentioned in this MS doc article. In this article you will find how to configure it explicitly too.

Here the example with your code and fluent API:

Models

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
            });
}
查看更多
登录 后发表回答