7

I want create a table with a primary key shadowed (out of the model).

public class Person
{
    public string Name { get; set; }
}

public class PersonEntityTypeConfiguration : IEntityTypeConfiguration<Person>
{
    public void Configure(EntityTypeBuilder<Person> builder)
    {
        builder.Property?
        builder.HasKey("Id")????
    }
}

Note: the real case is a different class and a value object (DDD).

Jhon Duck
  • 335
  • 3
  • 12
  • Have you tried `builder.HasKey("Id");`? – DavidG Jul 24 '18 at 17:05
  • @DavidG I can't test the project, but "HasKey" expects the name of a property and I can't assign a type – Jhon Duck Jul 24 '18 at 17:10
  • @GertArnold These are tries – Jhon Duck Jul 24 '18 at 17:11
  • @JhonDuck why dont you use a DTO wrapper? I mean keep your model class with the key property as it is, make its class internal and expose a DTO that does not have the key field.. I think this approach would be easier and correct from a DDD perspective. – taquion Jul 24 '18 at 17:29
  • If you want to walk the hard path take a look to custom [conventions] (https://blogs.msdn.microsoft.com/dotnet/2016/09/29/implementing-seeding-custom-conventions-and-interceptors-in-ef-core-1-0/) and to [this](https://stackoverflow.com/a/21686896/4430204) answer – taquion Jul 24 '18 at 17:31

2 Answers2

10

There are two ways to get this done. One is to define the property and then configure it as key (the order matters)

builder.Property<int>("ID")
    .HasColumnType("int")
    .ValueGeneratedOnAdd();
builder.HasKey("ID");

You probably want ValueGeneratedOnAddhere, because it's more or less the point of shadow properties to do everything under the hood.

I never like code in which the order of statements is a hidden requirement. It may lead to unexpected bugs. I would prefer the single-statement option:

builder.Property<int>("ID")
    .HasColumnType("int")
    .ValueGeneratedOnAdd()
    .HasAnnotation("Key", 0);

The value 0 in HasAnnotation is entered because it's mandatory. It has no bearing on the key generation.

I'm not yet sure if it's a good idea to use shadow properties in keys. I can't oversee which issues may appear when actually working with them. It may be a very good idea indeed.

Gert Arnold
  • 100,019
  • 29
  • 193
  • 278
3

I don't use the TypeBuilder a lot but this should be close:

public void Configure(EntityTypeBuilder<Person> builder)
{
    builder.Property<int>("id");
    builder.HasKey("Id");
}
luke
  • 34,649
  • 7
  • 57
  • 81
Henk Holterman
  • 250,905
  • 30
  • 306
  • 490