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...
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 and
AbstractService, not with
StudyTeamService`.
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();
}
}
}