Needing help with IL2CPP code stripping of Entity Framework Core

I have EF Core working in the editor, but in an IL2CPP build on Windows I get the following runtime error:

ExecutionEngineException: Attempting to call method 'Microsoft.EntityFrameworkCore.Metadata.Internal.ClrPropertySetterFactory[[Microsoft.EntityFrameworkCore.Metadata.IClrPropertySetter, Microsoft.EntityFrameworkCore, Version=3.1.18.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]]::CreateGeneric<ProjectCards.Data.ServerDatabaseContext,Microsoft.EntityFrameworkCore.DbSet`1[[ProjectCards.Data.Referral, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]],Microsoft.EntityFrameworkCore.DbSet`1[[ProjectCards.Data.Referral, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]>' for which no ahead of time (AOT) code was generated.

I’ve tried adding it to a link.xml file like this:

<assembly fullname="Microsoft.EntityFrameworkCore" preserve="all">
              <type fullname="Microsoft.EntityFrameworkCore.Metadata.Internal.ClrPropertySetterFactory`1" preserve="all">
                     <method signature="Microsoft.EntityFrameworkCore.Metadata.IClrPropertySetter CreateGeneric`3(ProjectCards.Data.ServerDatabaseContext,Microsoft.EntityFrameworkCore.DbSet`1,Microsoft.EntityFrameworkCore.DbSet`1)" preserve="all" />
              </type>
       </assembly>

I’ve also tried using the AotHelper from JSON.NET like this:

        [Preserve]
        private void ConfigureAot()
        {
            this.Log("Configuring AOT");
            AotHelper.EnsureType<ClrPropertySetterFactory_AOT>();
        }

        [Preserve]
        private class ClrPropertySetterFactory_AOT : ClrPropertySetterFactory
        {
            [Preserve]
            public ClrPropertySetterFactory_AOT()
            {
                CreateGeneric<ServerDatabaseContext, DbSet<ProjectCards.Data.Referral>, DbSet<ProjectCards.Data.Referral>>(null, null);

                throw new NotImplementedException();
            }
        }

Neither approach worked though. Any ideas what I’m doing wrong?

To put this together in my mind - is this the same question asked here? Unity's IL2CPP // AOT compilation mode compatibility · Issue #13099 · dotnet/efcore · GitHub

Yes it is. I haven’t made any progress on figuring it out, unfortunately.

I tried out another ORM (linq2db), and still running into IL2CPP issues with it as well. With that one its this call failing, which ultimately seems like the same issue I was having with Entity Framework that I got stuck on too.

ExecutionEngineException: Attempting to call method 'System.Linq.Expressions.Interpreter.LightLambda::MakeRun1<LinqToDB.DataProvider.PostgreSQL.NpgsqlProviderAdapter+NpgsqlBinaryImporter,System.UInt64>' for which no ahead of time (AOT) code was generated.
  at System.Func`2[T,TResult].Invoke (T arg) [0x00000] in <00000000000000000000000000000000>:0
  at System.Linq.Expressions.Interpreter.LightLambda.MakeDelegate (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
  at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate (System.Runtime.CompilerServices.IStrongBox[] closure) [0x00000] in <00000000000000000000000000000000>:0

I already have this in the link.xml, but it wasn’t enough to fix that issue.

  <assembly fullname="System.Core">
    <type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" />
  </assembly>

Unfortunately, these libraries often assume that the are executing in a JIT runtime environment, so they run into problems in an AOT environment.

This error might be a little more comprehensible than the original one. I think that you will need something like the AotHelper class for this case as well - only a link.xml will not correct this issue.

Can you provide any guidance on what it would be? “System.Linq.Expressions.Interpreter.LightLambda::MakeRun1” isn’t a method I can call for the AotHelper.

Oh, I did not realize that was not a public method, sorry. That makes things much more difficult. I don’t have a good solution then, unfortunately.

The best option is to use Unity 2022.2, where this should just work, or Unity 2021.3, where you can enable full generic sharing to avoid this as an option.

I think that you mentioned this project is on Unity 2020.3 though, right? I don’t have a solution there, short of using a library that works with an AOT runtime, unfortunately.

I wish I could use those newer ones, but I need to stick to an LTS release. I’ve also heard of too many performance issues from fellow VR developers on Unity 2021, so I cannot update to that either. I target the Meta Quest where performance is critical.

1 Like

Hey @emrys90

Here is the sample of link.xml to avoid issues with EntityFrameworkCore on AOT platforms (such as Android and iOS).

Also, I would highly recommend to instead of manual integration of EntityFrameworkCore and all the dependencies. You can use the bundle package that I made and tested on

  • Windows
  • Android
  • iOS
  • MacOS

It includes SQLite providers for each platform which works perfectly in a project with this setup

API Compatibility: .NET Standard 2.0 or 2.1
Backend: IL2CPP

The package almost doesn’t have it is own code, it is just a bundle of “right” dependencies and link.xml file to support EFCore + SQLite on mentioned platforms in player build.