none
EF 4.1 Code First - Ignore property of abstract base class RRS feed

  • Question

  • Hi,

    I have an existing schema with many tables that have common column definitions and I want to use an abstract base class to model this in my Code First entity model.

    In most cases this works fine without having to do anything special, but some of the tables have varying column types, eg. bit versus byte types for a column that represents a boolean value. In this cases, I have created an additional property in the derived class which I am mapping and I want the EF Code First Model to ignore the property on the abstract base class.

    However, using the Ignore method in the Fluent API on the base class property is not having any effect. When I query the entity, the EF throws an exception:

    Test method Tests.TestDataAccess.MyEntityQuery threw exception:
    System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Invalid column name 'IsActive'.

    Here is an extract of the code:

      public abstract class BaseEntity
      {
        public virtual int InstanceId { get; set; }
        public virtual string Name { get; set; }
        public virtual bool IsActive { get; set; }
      }
    
      public class MyEntity : BaseEntity
      {
        public override bool IsActive { get { return Convert.ToBoolean(ActiveByte); } set { ActiveByte = Convert.ToByte(value); } }
    
        public virtual byte ActiveByte { get; set; }
      }
    
      internal class MyEntityConfiguration : EntityTypeConfiguration<MyEntity>
      {
        public MyEntityConfiguration()
        {
          this.ToTable("MyEntities");
          this.HasKey(e => e.InstanceId);
          this.Property(e => e.InstanceId).HasColumnName("MyEntityId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
          this.Property(e => e.Name).HasColumnName("sName");
          this.Ignore(e => e.IsActive);
          this.Property(e => e.ActiveByte).HasColumnName("bActive");
        }
      }
    

    How can I configure this using the fluent api ?

    Thanks

     

     

    Tuesday, June 14, 2011 10:23 AM

All replies

  • Hi Graham,

    Welcome!

    According to your description, the subclass's IsActive has overide the supclass's property, If you want to ignore the IsActive property, you can add NotMapped attribution on it:

     public abstract class BaseEntity
      {  [Key]
        public virtual int InstanceId { get; set; }
        public virtual string Name { get; set; }
        public virtual bool IsActive { get; set; }
      }
    
      public class MyEntity : BaseEntity
      {
        [NotMapped]
        public override bool IsActive { get { return Convert.ToBoolean(ActiveByte); } set { ActiveByte = Convert.ToByte(value); } }
    
        public virtual byte ActiveByte { get; set; }
      }
      public class MyContext : DbContext
      {
        public DbSet<MyEntity> MyEntities { get; set; }
      }
    

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, June 15, 2011 12:01 PM
    Moderator
  • Hi Alan,

    thanks for your reply.

    Yes, the NotMapped data annotation works, but I would prefer to use the Fluent API.

    Is there a way to configure this using the Fluent API ?

    Thanks

     

     

    Wednesday, June 15, 2011 1:07 PM
  • Hi Graham,

    Thanks for your feedback!

    My mistake!

    Igore method can do it:

    public abstract class BaseEntity
      {  [Key]
        public virtual int InstanceId { get; set; }
        public virtual string Name { get; set; }
        public virtual bool IsActive { get; set; }
      }
    
      public class MyEntity : BaseEntity
      {
        public override bool IsActive { get { return Convert.ToBoolean(ActiveByte); } set { ActiveByte = Convert.ToByte(value); } }
    
        public virtual byte ActiveByte { get; set; }
      }
      public class MyContext : DbContext
      {
        public DbSet<MyEntity> MyEntities { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
          modelBuilder.Entity<MyEntity>().Ignore(e=>e.IsActive);
        }
      }
    

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, June 15, 2011 1:13 PM
    Moderator
  • Hi Alan,

    that is the point of my question.

    Using the Ignore method does not work.

     

    Wednesday, June 15, 2011 3:16 PM
  • Hi Graham,

    Thanks for your feedback.

    The code I provide works well on my computer, I think you can try, If it could work, please feel free to share your code here, thans for understanding

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, June 17, 2011 8:21 AM
    Moderator
  • Hi Graham,

    This is indeed a bug in EF and it should be fixed in the next release. Meanwhile you could either use a NotMapped attribute or make BaseEntity an interface

    Thanks for reporting this issue.

    • Proposed as answer by Andriy Svyryd Monday, June 20, 2011 8:22 PM
    Monday, June 20, 2011 8:22 PM