45

I am creating a greenfield application that uses EF Core which must talk to a legacy database. I want EF to ignore some of the columns in the database because they will eventually be deprecated and I don't want them in the new entity model. I can't remove them yet as the legacy system still relies on them.

For an unwanted database column called DeprecatedFeature, I want to do something like:

modelBuilder.Entity<MyEntity>(entity => {
   entity.HasKey(t => t.Id);
   entity.ToTable("MyEntity");
   entity.ColumnIgnore("DeprecatedFeature"); // <-- this is what I want to do
})

Right now, the best I can do is include the property and mark it as obsolete:

public class MyEntity 
{
    public int Id { get; set; }

    [Obsolete("Deprecated in latest version")]
    public string DeprecatedFeature { get; set; }
}

But that means I can't turn on "warnings as errors". I still need to run migrations on my database.

Similar questions: EF 4.x, EF Core skip column on load, Using EF Designer/EDMX and duplicate

Edit

I can see by the answers that there is some confusion about my question:

NotMapped is NOT the answer

NotMapped is used when you have a property in your model that you don't want in the database. My problem is the other way around. I have a column in my database that I don't want in my model.

Jonatan Dragon
  • 4,675
  • 3
  • 30
  • 38
Dr Rob Lang
  • 6,659
  • 5
  • 40
  • 60
  • What if you use `NotMappedAttribute' on those properties you want to ignore. http://www.learnentityframeworkcore.com/configuration/data-annotation-attributes/notmapped-attribute – Yared Nov 01 '17 at 15:14
  • Had a similar issue, solved by using [JsonIngore] attribute, data is not getting serialized for client world. – Alex Oct 08 '21 at 17:22
  • Columns (that are nullable or have a default) in db table but not in the EF Entity (model) are ignored by EF – GregJF Mar 10 '23 at 02:19
  • You could try to create interface from these properties and implement it explicitly. – kemsky Apr 22 '23 at 15:31

5 Answers5

58

You have two alternatives:

  1. Using NotMappedAttribute:

    public class MyEntity
    {
         public int Id { get; set; }    
         [NotMapped]
         public string DeprecatedFeature { get; set; }
    }
    
  2. Using FluentAPI:

    modelBuilder.Entity<MyEntity>().Ignore(c => c.DeprecatedFeature);
    
jurilents
  • 159
  • 1
  • 1
  • 10
Yared
  • 2,206
  • 1
  • 21
  • 30
  • 2
    Thanks for answering but you have misunderstood the question, so I have updated it. I have a column in the DB that I *don't want* in the model. – Dr Rob Lang Nov 01 '17 at 16:10
  • We are facing this issue for store procedure result model. We have added this FluentAPI in Context file but it throws error when we call our store procedure from code within that store procedure result model.Can you help me for the same? – Nikita Oct 20 '18 at 06:48
24

Just don't include that property in your entity class. EntityFramework should just ignore it then.

public class MyEntity 
{
    public int Id { get; set; }

    // Remove this property
    //public string DeprecatedFeature { get; set; }
}

You should be able to access this entity from the database without any problems, and your application code won't have access to the deprecated property. If you need write to this table, the deprecated column will need to either be nullable or have a default value.


Edit:

You can create a shadow property like this:

entity.Property(typeof(string), "DeprecatedFeature");

This will let EF be aware of the property (and include it in migrations), but the property doesn't need to exist on the entity type.

Entith
  • 679
  • 3
  • 15
  • 2
    The problem with this solution is that next time I run `add-migration`, it will create a migration that will remove the column from the database. At some point in the future I want to do that but right now it will cause an error in the legacy system. – Dr Rob Lang Nov 01 '17 at 16:11
  • 2
    Ah, when you said you were using a legacy database I assumed that you were not using migrations. – Entith Nov 01 '17 at 16:35
  • 2
    @Dr Rob Lang - You can use "Shadow Properties" for this. See my edit. – Entith Nov 01 '17 at 16:44
  • 1
    Ah! That looks just like what I need. I'll test tomorrow. Thank you. – Dr Rob Lang Nov 01 '17 at 21:29
  • This works for my situation too, where I am deprecating a poorly-normalized multi-valued field and replacing it with several fields that map to different columns. I want to keep the old Property in the entity via NotMapped, but have it persist to my new columns instead of the old ones. However, I'm not ready to remove the original column from the database yet, and adding NotMapped creates a migration that removes the column. Creating a shadow column the way you describe keeps the deprecated property in the database until I'm ready to delete it. – mikebridge Nov 22 '19 at 18:56
3

I didn't see an accepted answer to this question so here is mine. I believe that the thing called "shadow properties" is exactly what you need.

With a shadow property you can define a field in the table but don't add a property to your model class:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>()
        .Property<string>("DeprecatedFeature");
}
Sergiy
  • 1,912
  • 2
  • 16
  • 25
1

I have similar requirement, where I need the property in code but db populates the field. I used the following attribute under System.ComponentModel.DataAnnotations.Schema namespace

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]

This way, the property is mapped but is not populated when using entityframework.

salman_sali
  • 181
  • 2
  • 8
0

It is impossible to have one EF data model that is both:

  • A new version of your data model, that maps only a part of your database, and
  • Uses migrations to maintain your old database.

What you can do, is create a new EF data model. You will have the old one with migrations for maintaining your old database and the new one, without migrations, for your new application.

In the new one, you can simply skip columns (properties) you don't need.

Jonatan Dragon
  • 4,675
  • 3
  • 30
  • 38