Reputation: 7555
I'm having difficulty figuring out how to only map a base class in Entity Framework to my database, while preventing any information about classes that inherit it from being mapped to the database.
I created a simple example to highlight my difficulty where there is a base Worker
class, and a child class called Engineer
. For some reason, assume that I don't care to store details of the engineer... I only want my database to contain the information in the Worker
class.
So I've done the following:
class Program
{
static void Main(string[] args)
{
Engineer e = new Engineer();
e.Name = "George";
e.Focus = "Software";
MyDatabase db = new MyDatabase();
e.Save(db);
}
}
public class MyDatabase : DbContext
{
public DbSet<Worker> Workers { get; set; }
public MyDatabase() : base("mytempdb") { }
}
[NotMapped]
public class Engineer : Worker
{
public string Focus { get; set; }
}
public class Worker
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
public bool Save(MyDatabase db)
{
try
{
if (db.Workers.Any(w => w.ID == this.ID))
{
db.Workers.Attach(this);
db.Entry(this).State = System.Data.Entity.EntityState.Modified;
}
else
{
db.Workers.Add((Worker)this);
}
db.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine(e);
return false;
}
return true;
}
}
I am doing "Database First" design, and my database table looks like:
CREATE TABLE [dbo].Workers
(
[ID] INT NOT NULL PRIMARY KEY,
[Name] NVARCHAR(200) NULL,
[Discriminator] NVARCHAR(200) NULL
)
However, when I run my program, it is still looking for a entity to store Engineer
in. I've told it not to map it, hoping that it would only map the base class to the database:
System.InvalidOperationException: Mapping and metadata information could not be found for EntityType 'ConsoleApplication10.Engineer'.
Upvotes: 0
Views: 385
Reputation: 106820
I think you might have to map the entity to a new Worker
entity before saving so that entity framework doesn't look for the object's sub type—Engineer
.
For example:
public class Worker
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
public static FromWorker(Worker worker)
{
// example of mapping the entity
return new Worker
{
ID = worker.ID,
Name = worker.Name,
};
}
public bool Save(MyDatabase db)
{
try
{
Worker worker = Worker.FromWorker(this);
if (db.Workers.Any(w => w.ID == worker.ID))
{
db.Workers.Attach(worker);
db.Entry(worker).State = System.Data.Entity.EntityState.Modified;
}
else
{
db.Workers.Add(worker);
}
db.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine(e);
return false;
}
return true;
}
}
Upvotes: 1
Reputation: 11348
EDIT: You already use [NotMapped]
I did not see that first time sorry.
So i dont expect it to be in the model.
There is a do not map attribute for properties and equivalent fluent api option for whole classes.
[NotMapped]
public string BlogCode { get;set; }
and for a POCO inside the Context
public class MyDbContext : DbContext {
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
//Tell EF not to include these in DB. Ignore these please
// Anthing that EF picks and generates a table for that shoudl not be persisted
// modelBuilder.Ignore<EFpleaseIgnoreMe>();
modelBuilder.Ignore<YourType>();
}
}
Upvotes: 0