EF, Table per Hierarchy, property in abstract class

I'm wondering if I can use virtual properties defines in a base class (abstract) to create a link with an other concrete type.

For example :

public abstract class AbstractService
{
   public int Id {get;set;}

   public int? SiteId {get;set;}
   public virtual Site Site {get;set;}
}

public class StudyTeamService : AbstractService
{
   public int? RoleId {get;set;}
   public virtual Role Role {get;set;}
}


public abstract class AbstractSite
{
   public int Id {get;set;}

   public string Name {get;set;}
}

public class Site : AbstractSite
{
   public virtual ICollection<StudyTeamService> StudyTeamServices {get;set;}
}

I presume I have to add an annotation on the ICollection so that it know how to map correctly, but I can't find the correct one.

Do you guys have any idea ?

Seems that if I set [InverseProperty("Site")] on the ICollection, it crash with an error telling that the relation is not defined in the assembly...

Answers


I think the problem with your code is in

public class Site : AbstractSite
{
   public virtual ICollection<StudyTeamService> StudyTeamServices {get;set;}
}

since the relationship is between Site andAbstractService, not withStudyTeamService`.

The code below works for me:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;

namespace StackOverflow
{

    public abstract class AbstractService
    {
        public int Id { get; set; }
        public virtual Site Site { get; set; }

        public int SiteId { get; set; }
    }

    [Table("StudyTeamServices")]
    public class StudyTeamService : AbstractService
    {
        public virtual Role Role { get; set; }
    }

    public class Role
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }


    public abstract class AbstractSite
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class Site : AbstractSite
    {
        public virtual ICollection<AbstractService> StudyTeamServices { get; set; }
    }

    public class Context : DbContext
    {
        static Context()
        {
            Database.SetInitializer<Context>(null);
        }

        public DbSet<AbstractService> AbstractServices { get; set; }
        public DbSet<StudyTeamService> StudyTeamServices { get; set; }
        public DbSet<Site> Sites { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //Not EdmMetadata Table on DB
            //modelBuilder.Conventions.Remove<IncludeMetadataConvention>();

            modelBuilder.Configurations.Add(new AbstractServiceMap());
        }

    }

    public class AbstractServiceMap : EntityTypeConfiguration<AbstractService>
    {
        public AbstractServiceMap()
        {
            HasRequired(a => a.Site).WithMany(s => s.StudyTeamServices).HasForeignKey(a => a.SiteId);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var context = new Context();
            context.Database.Delete();
            context.Database.Create();

            var studyTeamService = new StudyTeamService();
            studyTeamService.Role = new Role { Name = "role1" };
            studyTeamService.Site = new Site { Name = "Site1" };

            context.StudyTeamServices.Add(studyTeamService);
            context.SaveChanges();
            Console.WriteLine("Done");
            Console.ReadLine();
        }
    }
}

Need Your Help

Adding MFC support to a Qt project

c++ qt mfc atl algorithmic-trading

I have a Qt project and would like to use an external library that includes "afxstr.h".