Prevent EF Model creation in secondary apps - c#

So I have a drop and recreate setup in my application's core project which is consumed by all of my apps in this solution. My model changes significantly enough to where I need this drop and recreate the database tables each time I recycle my app pool (app is in rapid development right now.) The problem is that if 2+ projects are kicked off at the same time, the drop and recreate steps on each other and many times there are missing tables.
I need a way to prevent, at runtime, the creation of the model based on a condition. I tried:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
if (condition)
return;
//...
base.OnModelCreating(modelBuilder);
}
but this is not working... the tables are still being created. How can I do this?

Not quite sure about your scenario.
For the development purposes, you can use different schema for your tables.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("applicationX");
}
If this is not possible, you can suffix/prefix table names for your entities.
If you need shared tables (data) by both application, you can compose all the database in any application sharing the same model building code.
Then, of course, you must somehow create "critical section" for your database recreation code (https://github.com/aspnet/EntityFramework/issues/3042), using Mutex or/and combined it e.g. with your own lock synchronization object (table) in your database.
If you need to construct a model (database) dynamically, e.g., use the dependancy injection to build model dynamically at single DB context:
/// <summary>
/// Formalization of entity framework DbContext model creation <see cref="DbContext.OnModelCreating"/>
/// </summary>
/// <remarks>
/// The reason for this explicit interface of the <see cref="DbContext.OnModelCreating"/> is to make compositions of several model builders into one
/// </remarks>
public interface IEntityFrameworkModelBuilder
{
void BuildModel(ModelBuilder modelBuilder);
}
public abstract class DbContextBase : DbContext
{
protected DbContextBase(DbContextOptions options, IEntityFrameworkModelBuilder modelBuilder) : base(options)
{
_modelBuilder = modelBuilder;
}
public virtual IEntityFrameworkModelBuilder ModelBuilder
{
get { return _modelBuilder ?? (_modelBuilder = new DefaultSchemaEntityFrameworkModelBuilder("dbo")); }
protected set { _modelBuilder = value; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
ModelBuilder.BuildModel(modelBuilder);
}
}
Of course, then you can create e.g. composit pattern class for your IEntityFrameworkModelBuilder:
/// <summary>
/// The composition of <see cref="IEntityFrameworkModelBuilder"/> used to construct <see cref="DbContext"/> model creation from several modules (tests).
/// </summary>
/// <seealso cref="DbContextOnModelCreatingAdaptingModelBuilder"/>
public class EntityFrameworkModelBuilderComposition : IEntityFrameworkModelBuilder, IList<IEntityFrameworkModelBuilder>
{
private readonly IList<IEntityFrameworkModelBuilder> _builders;
public EntityFrameworkModelBuilderComposition() : this(new IEntityFrameworkModelBuilder[0])
{}
public EntityFrameworkModelBuilderComposition(params IEntityFrameworkModelBuilder[] builders)
{
_builders = new List<IEntityFrameworkModelBuilder>(builders);
}
/// <summary>
/// Constructor to take list of builders as underlaying list so it is initialized with these builders and sharing the same reference.
/// </summary>
/// <param name="builders"></param>
public EntityFrameworkModelBuilderComposition(IList<IEntityFrameworkModelBuilder> builders)
{
_builders = builders ?? new List<IEntityFrameworkModelBuilder>();
}
public virtual void BuildModel(ModelBuilder modelBuilder)
{
foreach (var b in _builders)
{
b.BuildModel(modelBuilder);
}
}
}
Just adding, what you could find helpful sooner or later:
/// <summary>
/// The <see cref="IEntityFrameworkModelBuilder"/> implementation of a building model on the base of <see cref="DbContext"/> instance calling its <see cref="DbContext.OnModelCreating"/> protected method.
/// </summary>
/// <seealso cref="DbContextOnModelCreatingAdaptingModelBuilder"/>
/// <seealso cref="EntityFrameworkModelBuilderComposition"/>
public class DbContextOnModelCreatingAdaptingModelBuilder : IEntityFrameworkModelBuilder
{
private readonly Func<DbContext> _dbContextFactoryMethod;
public DbContextOnModelCreatingAdaptingModelBuilder(Func<DbContext> dbContextFactoryMethod)
{
_dbContextFactoryMethod = dbContextFactoryMethod;
}
public void BuildModel(ModelBuilder modelBuilder)
{
using (var dbContext = _dbContextFactoryMethod())
{
MethodInfo onModelCreating = dbContext.GetType().GetMethod("OnModelCreating", BindingFlags.NonPublic | BindingFlags.Instance);
onModelCreating.Invoke(dbContext, new object[] {modelBuilder});
}
}
}
Of course, all the mentioned points can/must be combined to get the desired behaviour. But it's not clear, how you evaluate the model differences, what
My model changes significantly enough to where I need this drop and recreate
means exactly regarding
the drop and recreate steps on each other and many times there are missing tables

Sadly, according to Microsoft, there does not seem to be a way to do it: https://github.com/aspnet/EntityFramework/issues/6346

Related

What are the ways to make property code-generated only

I am trying to create an abstract class which will contain properties and every entity in my solution will inherit this properties.
I do want that abstract class properties to be restricted from any user modification except the changes which are made by code.
What I want to achieve:
public abstract class SystemEntityBase
{
/// <summary>
/// Gets the date when entity was created.
/// </summary>
public DateTime Created { get; } = DateTime.UtcNow;
/// <summary>
/// Gets the date when entity was last active in the system.
/// </summary>
public DateTime LastActive { get; } = DateTime.UtcNow;
}
Because I am using read-only property, the EntityFrameworkCore will not add this fields to my database table when auto-generating the migration scripts.
I am curios what are possible solutions to restrict properties in my case while also create the database columns?
You should be able to use init only properties if you can use c# 9.0.
If I understood problem correctly - you can try using Backing Fields. For your Created property it can look something like that (for some reason using BackingFieldAttribute didn't work for me with my test SQLite and postgres setups, but fluent API did the trick):
public class SomeEntity
{
public DateTime Created => _created
private DateTime _created = DateTime.UtcNow;
}
And in OnModelCreating(ModelBuilder modelBuilder):
modelBuilder.Entity<SomeEntity>()
.Property(b => b.Created)
.HasField("_test");
Also it is possible to remove the need to setup all SomeEntity's by hand via some reflection magic.

EF Core OnDelete Not Available

I have an issue in our system where a process is attempting to replace a record and it causes a FK Exception and fails. We are using Microsoft.EntityFrameworkCore 2.2.2 in a .Net Standard 2.0 library. Most of the code was ported from an existing project that was not .Net Core.
I am trying to add cascade delete to the following model:
modelBuilder.Entity<TermEntity>()
.ToTable("Term", SchemaName)
.HasKey(k => new { k.TermId, k.TenantId });
by adding the following:
modelBuilder.Entity<TermEntity>()
.ToTable("Term", SchemaName)
.HasKey(k => new { k.TermId, k.TenantId });
.OnDelete(DeleteBehavior.Cascade);
but I then get an error C1061 'KeyBuilder' does not contain a definition for OnDelete which makes sense as that is what is returned from HasKey and the OnDelete is on ReferenceCollectionBuilder. None of the methods used above return one of those and all of them (yes I have tried moving it around) give a similar error. The signature of the method this is in looks like:
protected override void OnModelCreating(ModelBuilder modelBuilder)
When I look up some EF Core tutorials I don't see the methods I am using and instead I see HasOne, WithMany etc usually with OnDelete at the end of the chain. I also thought I read that Cascade was the default so not sure why I have the issue in the first place if that is the case.
Can someone point me in the right direction to getting this fixed please.
The TermEntity looks like:
public class TermEntity
{
/// <summary>
/// Gets or sets the term identifier.
/// </summary>
/// <value>
/// The term identifier.
/// </value>
public short TermId { get; set; }
/// <summary>
/// Gets or sets the Tenant identifier.
/// </summary>
/// <value>
/// The Tenant range identifier.
/// </value>
public short TenantId { get; set; }
/// <summary>
/// Gets or sets the value.
/// </summary>
/// <value>
/// The value.
/// </value>
public int Value { get; set; }
}
NB: I was asked to provide the class I was using in the example and realised that I had posted the wrong one. TermEntity is the class I am having problems with.

How to generalise access to DbSet<TEntity> members of a DbContext?

I have a DbContext with several of the following type of members:
public DbSet<JobLevel> JobLevels { get; set; }
public DbSet<Country> Countries { get; set; }
public DbSet<Race> Races { get; set; }
public DbSet<Language> Languages { get; set; }
public DbSet<Title> Titles { get; set; }
All these are where T: IdNamePairBase, which has Id and Name members only. I am trying desperately to find a common interface with which to access any of these members, to generalise the following MVC3 controller code into one controller:
public ActionResult Edit(DropDownListModel model, Guid)
{
var dbSet = _dbContext.Countries;
var newItems = model.Items.Where(i => i.IsNew && !i.IsDeleted).Select(i => new { i.Name });
foreach (var item in newItems)
{
if (!string.IsNullOrWhiteSpace(item.Name))
{
var undead = ((IEnumerable<IdNamePairBase>)dbSet).FirstOrDefault(p => p.Name.ToLower() == item.Name.ToLower());
if (undead != null)
{
// Assign new value to update to the new char. case if present.
undead.Name = item.Name;
undead.IsDeleted = false;
_dbContext.SaveChanges();
continue;
}
var newPair = new Country { Name = item.Name };
dbSet.Add(newPair);
_dbContext.SaveChanges();
}
}
return RedirectToAction("Edit", new {listName = model.ListName});
}
How could I go about resolving my problem that right now I need one controller for each of the DbContext members, like the one above is dedicated to DbSet<Country> Countries?
PARTIAL SOLUTION: Along lines similar to GertArnold's answer below, before I knew about the _dbContext.Set<T> all he highlights, I implemented this method on my context class to get sets of a specific type:
public IEnumerable<DbSet<T>> GetDbSetsByType<T>() where T : class
{
//var flags = BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance;
var props = GetType().GetProperties()
.Where(p => p.PropertyType.IsGenericType && p.PropertyType.Name.StartsWith("DbSet"))
.Where(p => p.PropertyType.GetGenericArguments().All(t => t == typeof(T)));
return props.Select(p => (DbSet<T>)p.GetValue(this, null));
}
Some generalization is possible by using
var dbSet = _dbContext.Set<T>
and putting most of your method in a method with a generics type parameter.
However, there should be a switch somewhere to decide which type should be specified and which type to create, because I think the type is supplied as a property of the model (is it?). So it probably won't really look elegant, but probably be a lot shorter, with DRY-er code.
To add on Gert Arnold's answer, I want to note that there is another method overload on the dbContext that returns a general DbSet from a type object:
var dbSet = dbContext.Set(typeof(T))
If you want to add blind an object, then create the object using the set.Create() method, or if you already have an object created with the "new" keyowrd, you can convert it by using (similar to this answer)
var entity = dbSet.Create();
dbSet.Add(entity);
DbEntityEntry entry = context.Entry(entity);
entry.CurrentValues.SetValues(yourObject);
I've been looking for an answer to this question and I've found that it is easy to do using the Managed Extensibility Framework. There is a quicker way at the bottom of this post, however MEF allows for a much more scalable approach.
MEF allows you to build dynamic access plugins from disparate Assemblies; however it can be used to quickly populate Collections within a single assembly application.In essence, we'll be using it as a safe way of reflecting our assembly back into the class. In order to make this fully functional, I'm also going to implement the Strategy Pattern to the Entity Framework Model.
Add a reference to your project, pointing to System.ComponentModel.Composition. This will give access to the MEF library.
Now, we need to implement the Strategy Pattern. If you don't have an Interfaces folder, create one, and add IEntity.cs, as below.
IEntity.cs
namespace Your.Project.Interfaces
{
/// <summary>
/// Represents an entity used with Entity Framework Code First.
/// </summary>
public interface IEntity
{
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>
/// The identifier.
/// </value>
int Id { get; set; }
}
}
Now, each of you concrete entities need to implement this Interface:
public class MyEntity : IEntity
{
#region Implementation of IEntity
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>
/// The identifier.
/// </value>
public int Id { get; set; }
#endregion
// Other POCO properties...
}
I find that it is best practice, not to create individual interfaces for each entity, unless you're working in a high testing environment. Pragmatically, interfaces should only be used where that level of abstraction is needed; mainly when more than one concrete class will inherit, or when working with an over-enthusiastic Inversion of Control engine. If you have interfaces for everything in your production model, your architecture more than likely, has major flaws. Anyway, enough of the rambling.
Now that we have all of our entities "strategised", we can use MEF to collate them and populate a collection within your context.
Within your context, add a new property:
/// <summary>
/// Gets a dynamically populated list of DbSets within the context.
/// </summary>
/// <value>
/// A dynamically populated list of DbSets within the context.
/// </value>
[ImportMany(typeof(DbSet<IEntity>))]
public IEnumerable<DbSet<IEntity>> Sets { get; private set; }
The [ImportMany(typeof(DbSet<IEntity>))] here, allows MEF to populate the collection.
Next, add the corresponding Export attribute to each DbSet within the context:
[Export(typeof(DbSet<IEntity>))]
public DbSet<MyEntity> MyEntities { get; set; }
Each of the Imported and Exported properties is known as a "part". The final piece to the puzzle is to compose those parts. Add the following to your context's constructor:
// Instantiate the Sets list.
Sets = new List<DbSet<IEntity>>();
// Create a new Types catalogue, to hold the exported parts.
var catalogue = new TypeCatalog(typeof (DbSet<IEntity>));
// Create a new Composition Container, to match all the importable and imported parts.
var container = new CompositionContainer(catalogue);
// Compose the exported and imported parts for this class.
container.ComposeParts(this);
Now, with any luck, you should have a dynamically populated list of DbSets, within your context.
I have used this method to allow easy truncating of all tables via an extension method.
/// <summary>
/// Provides extension methods for DbSet objects.
/// </summary>
public static class DbSetEx
{
/// <summary>
/// Truncates the specified set.
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <param name="set">The set.</param>
/// <returns>The truncated set.</returns>
public static DbSet<TEntity> Truncate<TEntity>(this DbSet<TEntity> set)
where TEntity : class, IEntity
{
set.ToList().ForEach(p => set.Remove(p));
return set;
}
}
I have added a method to the context to truncate the whole database.
/// <summary>
/// Truncates the database.
/// </summary>
public void TruncateDatabase()
{
Sets.ToList().ForEach(s => s.Truncate());
SaveChanges();
}
EDIT (Overhaul):
The solution above has now been depreciated. Some tweeking as had to be done to get this to work now. To make this work, you need to import the DbSets into a temporary collection of DbSet of type "object", then cast this collection to DbSet of your required interface type. For basic purposes, the IEntity interface will suffice.
#region Dynamic Table List
/// <summary>
/// Gets a dynamically populated list of DbSets within the context.
/// </summary>
/// <value>
/// A dynamically populated list of DbSets within the context.
/// </value>
public List<DbSet<IEntity>> Tables { get; private set; }
/// <summary>
/// Gets a dynamically populated list of DbSets within the context.
/// </summary>
/// <value>
/// A dynamically populated list of DbSets within the context.
/// </value>
[ImportMany("Sets", typeof (DbSet<object>), AllowRecomposition = true)]
private List<object> TableObjects { get; set; }
/// <summary>
/// Composes the sets list.
/// </summary>
/// <remarks>
/// To make this work, you need to import the DbSets into a temporary collection of
/// DbSet of type "object", then cast this collection to DbSet of your required
/// interface type. For basic purposes, the IEntity interface will suffice.
/// </remarks>
private void ComposeSetsList()
{
// Instantiate the list of tables.
Tables = new List<DbSet<IEntity>>();
// Instantiate the MEF Import collection.
TableObjects = new List<object>();
// Create a new Types catalogue, to hold the exported parts.
var catalogue = new TypeCatalog(typeof (DbSet<object>));
// Create a new Composition Container, to match all the importable and imported parts.
var container = new CompositionContainer(catalogue);
// Compose the exported and imported parts for this class.
container.ComposeParts(this);
// Safe cast each DbSet<object> to the public list as DbSet<IEntity>.
TableObjects.ForEach(p => Tables.Add(p as DbSet<IEntity>));
}
#endregion
Next, run the CompileSetsList() facade from the constructor (with best practices for Web shown):
public MvcApplicationContext()
{
// Enable verification of transactions for ExecuteSQL functions.
Configuration.EnsureTransactionsForFunctionsAndCommands = true;
// Disable lazy loading.
Configuration.LazyLoadingEnabled = false;
// Enable tracing of SQL queries.
Database.Log = msg => Trace.WriteLine(msg);
// Use MEF to compile a list of all sets within the context.
ComposeSetsList();
}
Then, just decorate your DbSet<>s like this:
/// <summary>
/// Gets or sets the job levels.
/// </summary>
/// <value>
/// The job levels.
/// </value>
[Export("Sets", typeof(DbSet<object>))]
public DbSet<JobLevel> JobLevels { get; set; }
Now it will work properly.

What's the fastest way to get an ObjectContext reference from an entity object?

I'm creating extensions for my EntityFramework objects as described in How to: Customize Generated Data Objects but in some of those extensions I need to get the instance's ObjectContext to look up some other values in the model. I've found Tip 24 – How to get the ObjectContext from an Entity but that was written a couple years ago, which is referenced in this similar SO question but I'm really hoping there's a better answer now.
Surely this must be something that's needed frequently enough that retrieval of an Entity's object context from the entity itself should be supported with an official method.
Thanks in advance for any more recent information on this implementation.
There is another solution, using connected properties.
Using connected properties would look like this (warning: untested code):
public partial class Database1Entities
{
private struct ObjectContextProperty { }
partial void OnContextCreated()
{
this.ObjectMaterialized += (_, e) =>
{
e.Entity.GetConnectedProperty<Database1Entities, ObjectContextProperty>().Set(this);
};
this.ObjectStateManager.ObjectStateManagerChanged += (_, e) =>
{
if (e.Action == CollectionChangeAction.Add)
{
e.Element.GetConnectedProperty<Database1Entities, ObjectContextProperty>().Set(this);
}
else if (e.Action == CollectionChangeAction.Remove)
{
e.Element.GetConnectedProperty<Database1Entities, ObjectContextProperty>().Set(null);
}
};
}
/// <summary>
/// Gets the object context for the entity. Returns <c>null</c> if the entity is detached.
/// </summary>
/// <param name="entity">The entity for which to return the object context.</param>
public static Database1Entities FromEntity(EntityObject entity)
{
return entity.GetConnectedProperty<Database1Entities, ObjectContextProperty>().GetOrConnect(null);
}
}
Then you can use Database1Entities.FromEntity to get the object context from an entity object. You can also define an actual property on the entity objects as well if you want:
public partial class Table1
{
/// <summary>
/// Gets the object context for this entity. Returns <c>null</c> if the entity is detached.
/// </summary>
public Database1Entities ObjectContext { get { return Database1Entities.FromEntity(this); } }
}
In this solution, the ObjectContext property on the entity objects is optional.
No there is not any such method. The described workaround looks like the only option because the entity is derived from EntityObject which is defined as:
[Serializable, DataContract(IsReference=true)]
public abstract class EntityObject : StructuralObject, IEntityWithKey,
IEntityWithChangeTracker, IEntityWithRelationships
{
...
}
As I know only IEntityWithRelationships.RelationshipManager leads to ObjectContext. This wasn't changed in EF 4.
Also it is not really common to access the context from the entity. I can imagine that this can be helpful in case of implementing Active Record Pattern on top of EF but in such case you would also have probably control over creating the context inside the static method of the entity so you should be able to set it to the entity. In other cases I would say that it is something you should avoid as much as possible.
This is what I use; it's a convention-based approach that is simple to add to a project.
First, add hooks to your object context:
public partial class Database1Entities
{
partial void OnContextCreated()
{
this.ObjectMaterialized += (_, e) =>
{
try
{
dynamic entity = e.Entity;
entity.ObjectContext = this;
}
catch (RuntimeBinderException)
{
}
};
this.ObjectStateManager.ObjectStateManagerChanged += (_, e) =>
{
if (e.Action == CollectionChangeAction.Add)
{
try
{
dynamic entity = e.Element;
entity.ObjectContext = this;
}
catch (RuntimeBinderException)
{
}
}
else if (e.Action == CollectionChangeAction.Remove)
{
try
{
dynamic entity = e.Element;
entity.ObjectContext = null;
}
catch (RuntimeBinderException)
{
}
}
};
}
}
This will attempt to dynamically set a property called ObjectContext on any entity that is associated with the object context.
Next, add an ObjectContext to the entity types:
public partial class Table1
{
/// <summary>
/// Gets or sets the context for this entity.
/// This should not be set by end-user code; this property will be set
/// automatically as entities are created or added,
/// and will be set to <c>null</c> as entities are detached.
/// </summary>
public Database1Entities ObjectContext { get; set; }
}
This solution does require an ObjectContext property to be added to each entity type.

Fluent NHibernate: How to tell it not to map a base class

I have been googling and stackoverflowing for the last two hours and couldn't find an answer for my question:
I'm using ASP.NET MVC and NHibernate and all I'm trying to do is to manually map my entities without mapping its base class. I'm using the following convention:
public class Car : EntityBase
{
public virtual User User { get; set; }
public virtual string PlateNumber { get; set; }
public virtual string Make { get; set; }
public virtual string Model { get; set; }
public virtual int Year { get; set; }
public virtual string Color { get; set; }
public virtual string Insurer { get; set; }
public virtual string PolicyHolder { get; set; }
}
Where EntityBase SHOULD NOT be mapped.
My NHibernate helper class looks like this:
namespace Models.Repository
{
public class NHibernateHelper
{
private static string connectionString;
private static ISessionFactory sessionFactory;
private static FluentConfiguration config;
/// <summary>
/// Gets a Session for NHibernate.
/// </summary>
/// <value>The session factory.</value>
private static ISessionFactory SessionFactory
{
get
{
if (sessionFactory == null)
{
// Get the connection string
connectionString = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;
// Build the configuration
config = Fluently.Configure().Database(PostgreSQLConfiguration.PostgreSQL82.ConnectionString(connectionString));
// Add the mappings
config.Mappings(AddMappings);
// Build the session factory
sessionFactory = config.BuildSessionFactory();
}
return sessionFactory;
}
}
/// <summary>
/// Add the mappings.
/// </summary>
/// <param name="mapConfig">The map config.</param>
private static void AddMappings(MappingConfiguration mapConfig)
{
// Load the assembly where the entities live
Assembly assembly = Assembly.Load("myProject");
mapConfig.FluentMappings.AddFromAssembly(assembly);
// Ignore base types
var autoMap = AutoMap.Assembly(assembly).IgnoreBase<EntityBase>().IgnoreBase<EntityBaseValidation>();
mapConfig.AutoMappings.Add(autoMap);
// Merge the mappings
mapConfig.MergeMappings();
}
/// <summary>
/// Opens a session creating a DB connection using the SessionFactory.
/// </summary>
/// <returns></returns>
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
/// <summary>
/// Closes the NHibernate session.
/// </summary>
public static void CloseSession()
{
SessionFactory.Close();
}
}
}
The error that I'm getting now, is:
System.ArgumentException: The type or
method has 2 generic parameter(s), but
1 generic argument(s) were provided. A
generic argument must be provided for
each generic parameter
This happens when I try to add the mappings. Is there any other way to manually map your entities and tell NHibernate not to map a base class?
IncludeBase<T>
AutoMap.AssemblyOf<Entity>()
.IgnoreBase<Entity>()
.Where(t => t.Namespace == "Entities");
Read more here http://wiki.fluentnhibernate.org/Auto_mapping :)
If you don't want to automap a class, I would recommend using IAutoMappingOverride<T>. I don't about your database, but it might look like:
public class CarOverride : IAutoMappingOverride<Car>
{
public void Override(AutoMapping<Car> mapping){
mapping.Id( x => x.Id, "CarId")
.UnsavedValue(0)
.GeneratedBy.Identity();
mapping.References(x => x.User, "UserId").Not.Nullable();
mapping.Map(x => x.PlateNumber, "PlateNumber");
// other properties
}
}
Assuming you keep these maps centrally located, you could then load them on your autoMap:
var autoMap = AutoMap.Assembly(assembly).IgnoreBase<EntityBase>().IgnoreBase<EntityBaseValidation>()
.UseOverridesFromAssemblyOf<CarOverride>();
I know it's an old question but I think that some things are missing here :
When you use IgnoreBase<T> you are telling that you don't want to map inheritance into your database but Fluent Nhibernate will still map your base class as an individual class while you don't tell it not to do that, so if you want to tell Fluent Nhibnernate not to map the class itself you should inherit DefaultAutoMapConfiguration class and override its bool ShouldMap(Type type) and return false if the type is any type that you don't want to map it at all.
When you use AutoMapping generally you don't need any other mapping classes or overrides unless you want to make a change in your mappings and it's not possible doing that using Conventions or you just want to override a small part of one class.(Although you can do the same using Conventions and Inspectors)
You can use IsBaseType convention for your automappings

Categories

Resources