Inherit a common base class in EF code first
Asked Answered
S

2

7

I'm converting my EF POCO project to Code first. I had changed the T4 template, so that all my entities use a base class, EntityBase, that provides them with some common functionality that is not persistence related.

If I use [NotMapped] attribute on EntityBase, all entities inherit this attribute and I get a The type 'X.X.Person' was not mapped, for any type I try to use with EF.

If I use [NotMapped] on all properties of EntityBase, I get a EntityType 'EntityBase' has no key defined. Define the key for this EntityType exception

FYI: I use Ef 4.3.1

Edit: part of the code:

[DataContract(IsReference = true)]
public abstract class EntityBase : INotifyPropertyChanged, INotifyPropertyChanging
{
    [NotMapped]
    public virtual int? Key
    {
        get { return GetKeyExtractor(ConversionHelper.GetEntityType(this))(this); }
    }
    //other properties and methods!
}

and then

[DataContract(IsReference = true), Table("Person", Schema = "PER")]
public abstract partial class Person : BaseClasses.EntityBase, ISelfInitializer
{
    #region Primitive Properties
    private int? _personID;
    [DataMember,Key]
    public virtual int? PersonID
    {
        get{ return _personID; }
        set{ SetPropertyValue<int?>(ref _personID, value, "PersonID"); }
    }
}

For these two classes there is not fluent api configuration.

Sublimate answered 27/8, 2012 at 12:5 Comment(0)
F
4

Try to define EntityBase as abstract, if it's possible for you, and put NotMapped... on the properties you don't want to map should do the trick.

Froissart answered 27/8, 2012 at 12:12 Comment(3)
@Sublimate well, you speak of CodeFirst and T4 template. Is this really CodeFirst ? Can you show where and how you do the relationship mapping ? Cause we do use a base abstract class in CodeFirst, and it's working fine...Rosalindrosalinda
I used EF database first and POCO. At that time I'd changed T4 so that all my classes inherit EntityBase. Now that we switched to code first, the T4 no longer exists.Sublimate
@Sublimate Ok. Could you please try to show us : the EntityBase class, an example of inheriting class, and the corresponding part of the context configuration ?Rosalindrosalinda
J
4

Are you trying to create a table of EntityBase (Great blog post about this : Table Per Type Inheritence) that all your entities share, or to simply create a base object so all your entities can use the same methods? I didn't have any problem with the code you posted above. Here's the entirety of an quick test app:

[DataContract(IsReference = true)]
public abstract class EntityBase
{
    [NotMapped]
    public virtual int? Key
    {
        get { return 1; } //GetKeyExtractor(ConversionHelper.GetEntityType(this))(this); }
    }
    //  other properties and methods!
}

[DataContract(IsReference = true)]
public partial class Person : EntityBase
{
    private int? _personID;
    [DataMember, Key]
    public virtual int? PersonID
    {
        get { return _personID; }
        set { _personID = value; }
    }
}

public class CFContext : DbContext
{
    public DbSet<Person> Employers { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

    }
}

class Program
{
    static void Main(string[] args)
    {
        Person p = new Person();
        Console.WriteLine(p.Key);
    }
}

Which created this table/database: enter image description here

Jegar answered 27/8, 2012 at 14:27 Comment(1)
Thanks. Yes I want to create just a base class. No inheritance from EntityBase happens in Database level. Unfortunately, the complete code is too large to upload somewhere. I should try and find a reason why this does not work in my code.Sublimate

© 2022 - 2024 — McMap. All rights reserved.