A-Sharabiani
A-Sharabiani

Reputation: 19329

How to set a Property of a subclass as the primary key using fluent API

This is my model:

  public class RepoDocument
  {
    public DocumentRecord Document { get; set; }

    public string Title { get; set; }

    public string Path { get; set; }
  }

This is the sub class definition:

public class DocumentRecord
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    // ... Other fields here...
}

What I need

I want to have Id as my primary key for the RepoDocument model.

I am using this code in my db context:

  public class DocumentsContext : DbContext
  {
    public DocumentsContext()
        : base("name=DbConnectionString")
    {

    }
    public DbSet<RepoDocument> DocumentsTable { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<RepoDocument>().HasKey<Guid>(c => c.Document.Id);
    }
  }

The problem

However, I am getting the following error when I run add-migration in the Package Manager Console:

The properties expression 'c => c.Document.Id' is not valid. The expression should represent a property: C#: 't => t.MyProperty' VB.Net: 'Function(t) t.MyProperty'. When specifying multiple properties use an anonymous type: C#: 't => new { t.MyProperty1, t.MyProperty2 }' VB.Net: 'Function(t) New With { t.MyProperty1, t.MyProperty2 }'.

Question

How can I set the property of a sub-class of my model as the primary key of the database using fluent API?

Upvotes: 1

Views: 772

Answers (2)

Aron
Aron

Reputation: 15772

Your question is incorrect. You should be using inheritance.

public abstract class RepoDocument
{
    public Guid Id { get; set; }

    public string Title { get; set; }

    public string Path { get; set; }
}

public class Document : RepoDocument
{

    public string Name { get; set; }

    // ... Other fields here...
}

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<RepoDocument>().ToTable("RepoDocument");
        modelBuilder.Entity<Document>().ToTable("DocumentRecord");
    }

Upvotes: 3

Uladz
Uladz

Reputation: 1968

I suppose, you cannot, if your sub-class (btw, I've read sub-class as descendant first time) is used as entity - it will be stored in separate table, but your RepoDocument will have no key in that case.

I'm not sure, if it's possible, if you will register DocumentRecord as ComplexType, but you could try. it will be stored in the same table in that case, so sounds possible.

You could create separate type for configuration, then add it inside OnModelCreating.

public class DocumentRecordConfiguration: ComplexTypeConfiguration<DocumentRecord> 
{
    public DocumentRecordConfiguration()
    {
         /* use fluent api here */
    }
}

Upvotes: 2

Related Questions