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? https://github.com/dotnet/efcore/issues/13099#issuecomment-1458122677

[quote=“JoshPeterson”, post:2, topic: 911371]
To put this together in my mind - is this the same question asked here? https://github.com/dotnet/efcore/issues/13099#issuecomment-1458122677
[/quote]
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.

[quote=“JoshPeterson”, post:4, topic: 911371]
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.
[/quote]
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.

[quote=“emrys90”, post:5, topic: 911371]
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.
[/quote]

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.

[quote=“JoshPeterson”, post:6, topic: 911371]
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.
[/quote]
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