Search code examples
c#interfaceentity-framework-coreef-code-first-mapping

CodeFirst EF Core - Implementing interfaces possible?


I'm a little new to code-first in EF Core and I'm trying a few things out and I'm a little confused how to implement the below (or indeed whether it can be implemented or not).

In my model I have a class that maps entities to cases, with the following mapping class

public class CaseEntity
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CaseEntityId { get; set; }
    
    public int CaseId { get; set; }
    public CaseModel Case { get; set; }
    public Guid EntityId { get; set; }
    public EntityModel Entity { get; set; }
}

I am now implementing the EntityModel object. However an entity can be either a Person or a Company. Both these have common properties, but there are some natural differences. What I wanted to do is create an IEntityModel interface and two classes as below

public class CaseEntity
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CaseEntityId { get; set; }
    
    public int CaseId { get; set; }
    public CaseModel Case { get; set; }
    public Guid EntityId { get; set; }
    public IEntityModel Entity { get; set; }
}

public interface IEntityModel
{
    Guid EntityId { get; set; }
    PostalAddress PrincipalAddress { get; set; }
}

public class CompanyEntity : IEntityModel
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid EntityId { get; set; }
    public string CompanyName { get; set; }
    public PostalAddress PrincipalAddress { get; set; }
}

public class PersonEntity : IEntityModel
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid EntityId { get; set; }
    public PostalAddress PrincipalAddress { get; set; }
    public string FirstNames { get; set; }
    public string Surname { get; set; }
}

When I try to build this I get the error

The property 'CaseEntity.Entity' is of an interface type ('IEntityModel'). If it is a navigation, manually configure the relationship for this property by casting it to a mapped entity type.

Otherwise, ignore the property using the [NotMapped] attribute or 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

I'm not 100% certain I can do what I'm trying to do. Searching around has left me a little confused (is that a solution to implement kind of functionality like, or should I use implement an entity class that has all the properties need to support a Company or a Person?)


Solution

  • I think it would be better if you create a base class

    public class EntityModel:IEntityModel
    {
       [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
       public  int EntityId { get; set; }
       publlic  PostalAddress PrincipalAddress { get; set; }
    }
    

    CompanyEntity

    public class CompanyEntity : EntityModel
    {
        public string CompanyName { get; set; }
    }
    

    CaseEntity

    public class CaseEntity
        
        {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int CaseEntityId { get; set; }
        
        
        public int CaseId { get; set; }
        public CaseModel Case { get; set; }
    
        public int EntityId { get; set; }
        public virtual EntityModel EntityModel { get; set; }
        }