I am looking to retrofit a database to an existing codebase with as little pain as possible using NHibernate and an sqlite database. I would like to go about this by using the AutoMapper to map the fields that I tag with a [DatabaseField] custom attribute for any object that inherits from a custom DatabaseObject class. Anything marked with a [Cascade] custom attribute will be cascaded. I have the following code in a test project at the moment:
Entities to map:
class Scan : DatabaseObject
{
[DatabaseField]
public virtual string Name { get; set; }
[DatabaseField]
public virtual DateTime ScanDate { get; set; }
[DatabaseField]
[Cascade]
public virtual Scanner Scanner { get; set; }
public DateTime ManufactureDate { get; set; }
}
class Scanner : DatabaseObject
{
[DatabaseField]
public virtual string Name { get; set; }
}
Session setup:
ProjectConfiguration pcfg = new ProjectConfiguration();
var sessionFactory = Fluently.Configure()
.Database(SQLiteConfiguration.Standard.UsingFile("theTestScannerDatabase.sqlite"))
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Scan>(pcfg)
.Override<Scan>(x => x.IgnoreProperty(y => y.ManufactureDate)).Conventions.Setup(x => x.AddFromAssemblyOf<Scan>())))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
return sessionFactory.OpenSession();
Project Configuration object
public class ProjectConfiguration : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Type type)
{
return type.BaseType == typeof(DatabaseObject);
}
public override bool ShouldMap(Member member)
{
return member.MemberInfo.GetCustomAttributes().Contains(new DatabaseField());
}
}
The problem is with the "ManufactureDate" field which the automapper has tried to map and is upset that it isn't a virtual property, and similar things happen with private properties. I don't want to map every property of my objects to the database. I thought that the tags and the stuff in the ShouldMap overrides should take care of this.
The exception:
InvalidProxyTypeException: The following types may not be used as proxies:
SQLiteTestingApp.Scan: method get_ManufactureDate should be 'public/protected virtual' or 'protected internal virtual'
SQLiteTestingApp.Scan: method set_ManufactureDate should be 'public/protected virtual' or 'protected internal virtual'
For the record, if I remove this field everything else maps exactly how I want it to.
I have read about the Override and OverrideAll methods that I've tried to use to explicitly exclude these fields, but it doesn't seem to have any effect. I left an example of this attempt in my code snippet above.
So I guess I have two questions:
Thanks in advance
Take a look at the documentation for ignoring properties.
You can use the IgnoreProperty
method.
.Override<Scan>(map =>
{
map.IgnoreProperty(x => x.ManufactureDate);
});
All properties/methods in an entity also need to be virtual or implement an interface as per documentation for persistent classes.
A central feature of NHibernate, proxies, depends upon the persistent class being non-sealed and all its public methods, properties and events declared as virtual. Another possibility is for the class to implement an interface that declares all public members.