I currently create a project with Xamarin.Forms and SQLite. Therefore I use CodeFirst for my database creation.
My database works without problems when creating or adding primitive elements or edit existing ones.
But even it works here my database model:
private string _path = string.Empty;
public MyDatabaseContext()
{
_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "..", "Library", "Monitoring_Tool_LocalDb.db");
this.Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite($"Filename={_path}");
}
Including the following sets for example
public DbSet<MyMainObject> MyMainObjects { get; set; }
public DbSet<MySubObject> MySubObjects { get; set; }
The classes:
// This class includs all base elements and is only there to get the
// minimum required attributes (could also be defined as abstract)
public class BaseClassElement
{
public Int64 Id { get; set; }
public Guid SomeGuidElement { get; set; }
public DateTime LastChange { get; set; }
}
public class MyMainObject : BaseClassElement
{
public string Designation { get; set; }
public virtual ICollection<MySubObject> MySubObjects { get; set; }
}
public class MySubObject: BaseClassElement
{
public string Designation { get; set; }
public virtual MyMainObject MyMainObject { get; set; }
}
Now to my problem:
If I now add a main object to the database like:
db.MyMainObjects.Add(myObjectWithNewData);
db.SaveChanges();
Everything went well. The object was added and I also used DateTime.Now to set the last change. Also I set the Guid to Guid.Empty.
Now if I try to do this: (I know, I could write less but I tried every method in every order to prevent that some error is happening there but nothing worked...)
// Element loaded from database without problems
var dbMainObject = db.MyMainObjects.Include("MySubObjects").SingleOrDefault(s => s.Id == myParameterGivenId);
var newlyGeneratedSubObject = new MySubObject()
{
MyMainObject = dbMainObject,
... // Other data set
};
db.MySubObjects.Add(newlyGeneratedSubObject);
dbMainObject.MySubObjects.Add(newlyGeneratedSubObject);
db.SaveChanges();
The method will throw the following exception:
Attempting to JIT compile method '(wrapper runtime-invoke) :runtime_invoke_void_this__long_byte_object_DateTime_object_object_Guid_object_int (object,intptr,intptr,intptr)' while running in aot-only mode.
This error is also referencing to the following page like this:
See https://developer.xamarin.com/guides/ios/advanced_topics/limitations/
I use the following nuget packages:
Microsoft.EntityFrameworkCore.Sqlite (2.0.1)
Xamarin.Forms (2.5.0.122203)
WinInsider.System.Net.Http.Formatting (1.0.5)
Newtonsoft.Json (10.0.3)
NETStandard.Library (2.0.1)
This is what I tried so far
Method OnConfiguring added:
optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
(therfore I used manually tracking)
db.Entry<MyElement>(myObjectFromElement).State = EntityState.Added;
Also db.Database.ExecuteSqlCommand("INSERT ...")
And db.Set<MyElement>().Add(myObjectFromElement)
Edit 1:
Need to mention: This error is only caused on the real runtime device. I tested it with an iPhone X Latest version and an iPad (Don't know which generation exactly but it's also on the latest version 12.2.5)
In the simulator everything went well.
Edit 2:
Changed context name
Edit 3:
Well, I finally got my stack trace. (Error hasn't changed, I just have more detailed informations)
System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) <0x100b2b000 + 0x0002f> in :0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <0x100ca6040 + 0x00028> in :0
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Exception source) <0x100ca6080 + 0x00023> in :0
at System.Linq.Expressions.Interpreter.ExceptionHelpers.UnwrapAndRethrow (System.Reflection.TargetInvocationException exception) <0x1026e2fe0 + 0x0001b> in <98d8ae0ba2c1456c96653359c4b1be27#c1614e788b2679307c28b34eca2b14d3>:0
at System.Linq.Expressions.Interpreter.NewInstruction.Run (System.Linq.Expressions.Interpreter.InterpretedFrame frame) <0x1026de640 + 0x0005f> in <98d8ae0ba2c1456c96653359c4b1be27#c1614e788b2679307c28b34eca2b14d3>:0
at System.Linq.Expressions.Interpreter.Interpreter.Run (System.Linq.Expressions.Interpreter.InterpretedFrame frame) <0x1026c5cd0 + 0x00087> in <98d8ae0ba2c1456c96653359c4b1be27#c1614e788b2679307c28b34eca2b14d3>:0
at System.Linq.Expressions.Interpreter.LightLambda.Run1[T0,TRet] (T0 arg0) <0x1026d5570 + 0x00073> in <98d8ae0ba2c1456c96653359c4b1be27#c1614e788b2679307c28b34eca2b14d3>:0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry+OriginalValues..ctor (Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry) <0x10360db50 + 0x0003f> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.EnsureOriginalValues () <0x1035abd50 + 0x0003b> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntrySubscriber.SnapshotAndSubscribe (Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry) <0x1035afc30 + 0x00053> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking (Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry) <0x1035d1cb0 + 0x001fb> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState (Microsoft.EntityFrameworkCore.EntityState oldState, Microsoft.EntityFrameworkCore.EntityState newState, System.Boolean acceptChanges) <0x1035a9ce0 + 0x00537> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState (Microsoft.EntityFrameworkCore.EntityState entityState, System.Boolean acceptChanges, System.Boolean forceStateWhenUnknownKey) <0x1035a9740 + 0x000fb> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction (Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntryGraphNode node) <0x1035a6e20 + 0x00113> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph (Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntryGraphNode node, System.Func`2[T,TResult] handleNode) <0x1035a6480 + 0x00047> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph (Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry rootEntry, Microsoft.EntityFrameworkCore.EntityState entityState, System.Boolean forceStateWhenUnknownKey) <0x1035a6b00 + 0x0018b> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.NavigationCollectionChanged (Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry, Microsoft.EntityFrameworkCore.Metadata.INavigation navigation, System.Collections.Generic.IEnumerable
1[T] added, System.Collections.Generic.IEnumerable
1[T] removed) <0x1035b2fd0 + 0x0041f> in :0at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.NavigationCollectionChanged (Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry, Microsoft.EntityFrameworkCore.Metadata.INavigation navigation, System.Collections.Generic.IEnumerable
1[T] added, System.Collections.Generic.IEnumerable
1[T] removed) <0x1035af910 + 0x00093> in :0at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectNavigationChange (Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry, Microsoft.EntityFrameworkCore.Metadata.INavigation navigation) <0x1035a31b0 + 0x00573> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectChanges (Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry) <0x1035a2c80 + 0x00343> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectChanges (Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IStateManager stateManager) <0x1035a2a10 + 0x001ff> in :0
at Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges () <0x103598dd0 + 0x0004b> in :0
at Microsoft.EntityFrameworkCore.DbContext.TryDetectChanges () <0x1034b39f0 + 0x0005f> in :0
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges (System.Boolean acceptAllChangesOnSuccess) <0x1034b38f0 + 0x00027> in :0
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges () <0x1034b38b0 + 0x00023> in :0
at MobileClient.Communicator.MyCommunicator.Add (Client.Businesslogic.ViewModels.MyElementViewModel myElement, System.Int64 roomTypeId) <0x102fc0250 + 0x0063b> in <1fe0ef9dc3fa4068840d6bf326c56b38#c1614e788b2679307c28b34eca2b14d3>:0
at Mobile.MobileClient.Skins.MySkins.AddElementUserControl.AddElementSave (System.Object sender, System.Object e) <0x102f61090 + 0x000ff> in <1fe0ef9dc3fa4068840d6bf326c56b38#c1614e788b2679307c28b34eca2b14d3>:0
This error is caused by a limitation on the size of arguments that can be passed to a dynamic call in Xamarin.iOS. The current plan is for the fix to be included in the 15.7 release (i.e. Xamarin.iOS 11.9).
See https://bugzilla.xamarin.com/show_bug.cgi?id=59184 for more details on the Xamarin.iOS issue.
There is also some information and workarounds customers have tried on the corresponding tracking issue for EF Core at https://github.com/aspnet/EntityFrameworkCore/issues/9249.