fluent-nhibernate icon indicating copy to clipboard operation
fluent-nhibernate copied to clipboard

FluentConfigurationException exception on Xamarin.Forms with Sqlite

Open m4rkyx opened this issue 4 years ago • 1 comments

Hi guys,

Recently I tried to port a logic from a WPF application to a Xamarin.Forms app. Both are using NHibernate with SQLite.

At first, it seemed easy but I got a lot of errors while creating the session factory in the Xamarin.Forms. I read some posts about writing my own Mono SQLite driver, so I did based on an example. I also added a reference to Mono.Data.Sqlite in my Android project and get rid of a lots of "cannot load DLL" exceptions.

But now, I still have a FluentConfigurationException while creating the session factory. The same code works well in a WPF application with SQLite.

E/mono-rt (11189): [ERROR] FATAL UNHANDLED EXCEPTION: FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
E/mono-rt (11189):
E/mono-rt (11189): ---> System.FieldAccessException: Field `XXX.Domain.Common.BaseClasses.Entity:<Id>k__BackingField' is inaccessible from method `(wrapper dynamic-method) XXX.Domain.Audits.CashDrawerOpening: (object)'

The Entity class is indeed composed of a private backing field and there is no problem in WPF.

  public abstract class Entity
  {
      protected long Id { get; }
      public static class Expressions<T> where T : Entity
      {
          public static readonly Expression<Func<T, object>> Id = x => x.Id;
      }

      // rest of the implementation
    }

The only difference between both is the SQLiteConfiguration in WPF between MonoSqliteConfiguration in Xamarin.Forms

WPF Session Factory builder :

return Fluently.Configure()
                .Database(SQLiteConfiguration.Standard.ConnectionString(connectionString))
                .Mappings(m => m.FluentMappings
                    .AddFromAssembly(Assembly.GetExecutingAssembly())
                    .Conventions.Add(
                        ForeignKey.EndsWith("Id"),
                        ConventionBuilder.Property.When(criteria => criteria.Expect(x => x.Nullable, Is.Not.Set), x => x.Not.Nullable()))
                    .Conventions.Add<RelationshipConventions>()
                    .Conventions.Add<IdConvention>()
                )
                .ExposeConfiguration(x => new SchemaUpdate(x).Execute(true, true))
                .BuildSessionFactory();

Xamarin.Forms Session Factory builder :

return Fluently.Configure()
                .Database(MonoSqliteConfiguration.Standard.ConnectionString(connectionString))
                .Mappings(m => m.FluentMappings
                    .AddFromAssembly(Assembly.GetExecutingAssembly())
                    .Conventions.Add(
                        ForeignKey.EndsWith("Id"),
                        ConventionBuilder.Property.When(criteria => criteria.Expect(x => x.Nullable, Is.Not.Set), x => x.Not.Nullable()))
                    .Conventions.Add<RelationshipConventions>()
                    .Conventions.Add<IdConvention>()
                )
                .ExposeConfiguration(x => new SchemaUpdate(x).Execute(true, true))
                .BuildSessionFactory();

The implementation of the MonoSqliteConfiguration can be found here https://stackoverflow.com/questions/7626251/using-nhibernate-and-mono-data-sqlite

Package informations :

  • FluentNHibernate : 3.1.0
  • NHibernate : 5.3.5
  • Xamarin.Forms : 5.0.0.1931
  • Xamarin.Android SDK : 11.1.0.26
  • Target Android API 29

Do you have any idea of what is going on ?

Thank you for your help ! :)

Michael

[EDIT]

After defining the Id property as protected with a setter, it works. protected virtual long Id { get; set; }

So, there is a problem with the reflection between an WPF app (netFramework 4.8) and the mono-rt ?

m4rkyx avatar Feb 05 '21 09:02 m4rkyx

It seems that you would probably need to switch default access strategy to property.

hazzik avatar Feb 17 '21 08:02 hazzik