Search Unity

Question Needing help with IL2CPP code stripping of Entity Framework Core

Discussion in 'Windows' started by emrys90, Mar 7, 2023.

  1. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    I have EF Core working in the editor, but in an IL2CPP build on Windows I get the following runtime error:
    Code (CSharp):
    1. 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:
    Code (CSharp):
    1. <assembly fullname="Microsoft.EntityFrameworkCore" preserve="all">
    2.               <type fullname="Microsoft.EntityFrameworkCore.Metadata.Internal.ClrPropertySetterFactory`1" preserve="all">
    3.                      <method signature="Microsoft.EntityFrameworkCore.Metadata.IClrPropertySetter CreateGeneric`3(ProjectCards.Data.ServerDatabaseContext,Microsoft.EntityFrameworkCore.DbSet`1,Microsoft.EntityFrameworkCore.DbSet`1)" preserve="all" />
    4.               </type>
    5.        </assembly>
    I've also tried using the AotHelper from JSON.NET like this:
    Code (CSharp):
    1.         [Preserve]
    2.         private void ConfigureAot()
    3.         {
    4.             this.Log("Configuring AOT");
    5.             AotHelper.EnsureType<ClrPropertySetterFactory_AOT>();
    6.         }
    7.  
    8.         [Preserve]
    9.         private class ClrPropertySetterFactory_AOT : ClrPropertySetterFactory
    10.         {
    11.             [Preserve]
    12.             public ClrPropertySetterFactory_AOT()
    13.             {
    14.                 CreateGeneric<ServerDatabaseContext, DbSet<ProjectCards.Data.Referral>, DbSet<ProjectCards.Data.Referral>>(null, null);
    15.  
    16.                 throw new NotImplementedException();
    17.             }
    18.         }
    Neither approach worked though. Any ideas what I'm doing wrong?
     
  2. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,930
  3. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    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.
    Code (CSharp):
    1. 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.
    2.   at System.Func`2[T,TResult].Invoke (T arg) [0x00000] in <00000000000000000000000000000000>:0
    3.   at System.Linq.Expressions.Interpreter.LightLambda.MakeDelegate (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
    4.   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.
    Code (CSharp):
    1.   <assembly fullname="System.Core">
    2.     <type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" />
    3.   </assembly>
     
  4. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,930
    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.
     
  5. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    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.
     
  6. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,930
    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.
     
  7. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    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.
     
    bn-l likes this.