Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[entityframeworkcore] Query throws Exception with Xamarin iOS when linking #3394

Closed
divega opened this issue Feb 5, 2018 · 23 comments
Closed
Labels
iOS Issues affecting Xamarin.iOS question The issue is a question

Comments

@divega
Copy link

divega commented Feb 5, 2018

From @rob2212 on November 2, 2017 16:29

When I query a DbSet e.g. with a simple ToList() call I get the exception shown below. The exception is only thrown on real iOS device. It works with the iOS emulator.

var test = context.Images.ToList();

Exception message: The type initializer for 'Microsoft.EntityFrameworkCore.Query.ResultOperators.Internal.TrackingExpressionNode' threw an exception.
Stack trace:   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.get_NodeTypeProvider () [0x0000a] in <0998bf911f014e7884d2695c95a67016>:0 
  at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler+<>c__DisplayClass15_0`1[TResult].<Execute>b__0 () [0x00000] in <0998bf911f014e7884d2695c95a67016>:0 
  at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc] (System.Object cacheKey, System.Func`1[TResult] compiler) [0x0001f] in <0998bf911f014e7884d2695c95a67016>:0 
  at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult] (System.Object cacheKey, System.Func`1[TResult] compiler) [0x00000] in <0998bf911f014e7884d2695c95a67016>:0 
  at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult] (System.Linq.Expressions.Expression query) [0x00069] in <0998bf911f014e7884d2695c95a67016>:0 
  at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult] (System.Linq.Expressions.Expression expression) [0x00000] in <0998bf911f014e7884d2695c95a67016>:0 
  at Remotion.Linq.QueryableBase`1[T].GetEnumerator () [0x0000c] in <4c6b24174f1a4a3a9c2e761b70716a02>:0 
  at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1[TEntity].System.Collections.Generic.IEnumerable<TEntity>.GetEnumerator () [0x00006] in <0998bf911f014e7884d2695c95a67016>:0 
  at System.Collections.Generic.List`1[T]..ctor (System.Collections.Generic.IEnumerable`1[T] collection) [0x00062] in <a89624c267f94034b6cf9aa0c56f8864>:0 
  at System.Linq.Enumerable.ToList[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x00018] in <773264786149499a986a13db6a7d46fe>:0 
  at Erdmann.FW.LocationDatabase.DatabaseContentBuilder.Run (Erdmann.FW.LocationDatabase.LocationDbContext context) [0x00014] in E:\IRISSYS\Source\OP-Tools\Erdmann\Erdmann.FW.LocationDatabase\Erdmann.FW.LocationDatabase\DatabaseContentBuilder.cs:25 
  at Erdmann.FW.LocationDatabase.DatabaseManager.FillDatabase (Erdmann.FW.LocationDatabase.DataSources.IDataSource source) [0x0002a] in E:\IRISSYS\Source\OP-Tools\Erdmann\Erdmann.FW.LocationDatabase\Erdmann.FW.LocationDatabase\DatabaseManager.cs:64 
  at TestApp.MainViewModel.Run () [0x00049] in E:\IRISSYS\Source\OP-Tools\Erdmann\Erdmann.FW.LocationDatabase\TestApp\TestApp.Shared\MainViewModel.cs:56 

The problem seems to be the linking behavior with the Xamarin project. I've tried to disable linking for some assemblies in the iOS Xamarin projefct under iOS Build:

--linkskip=Microsoft.EntityFrameworkCore --linkskip=Microsoft.EntityFrameworkCore.Relational --linkskip=Microsoft.EntityFrameworkCore.Sqlite --linkskip=Remotion.Linq

That didn't work. However disable linking completely does work (set Link Behavior to 'Don't Link'). But this can only be a temporary workaround not a final solution for production deployment.

Further technical details

EF Core version: v2.0.0
Database Provider: Microsoft.EntityFrameworkCore.Sqlite
Operating system: Windows 10 / iOS 11.1
IDE: Visual Studio 2017 (15.4.1)

Copied from original issue: dotnet/efcore#10207

@divega
Copy link
Author

divega commented Feb 5, 2018

From @ajcvickers on November 6, 2017 20:40

@rob2212 Would it be possible for you to post a code listing or project that reproduces what you are seeing? It looks like this is likely a Xamarin issue, but we would like to investigate before potentially filing an issue with them.

@divega
Copy link
Author

divega commented Feb 5, 2018

From @rob2212 on November 7, 2017 6:6

I will prepare sample project for reproduction later on.

@divega
Copy link
Author

divega commented Feb 5, 2018

From @rob2212 on November 8, 2017 8:56

@ajcvickers I've created a test project which you can use to reproduce the issue. I've inserted some warnings at the relevant places. Where can I upload it? Attachments here can only be 10 MB.

@divega
Copy link
Author

divega commented Feb 5, 2018

From @ajcvickers on November 8, 2017 16:52

@rob2212 Two things to try:

  • Many people just creat a new github repo and put the project there
  • Clean the project and, given that NuGet can restore packages needed, the cleaned. unbuilt project may be smalll enough to attach.

@divega
Copy link
Author

divega commented Feb 5, 2018

From @rob2212 on November 9, 2017 11:8

@ajcvickers
TestApp.zip

@divega
Copy link
Author

divega commented Feb 5, 2018

From @eusebiu on November 13, 2017 20:37

Any news on this? Thanks!

@divega
Copy link
Author

divega commented Feb 5, 2018

From @NPadrutt on November 14, 2017 10:48

I have the same issue with the extension ToListAsync().

@divega
Copy link
Author

divega commented Feb 5, 2018

From @eusebiu on November 16, 2017 19:4

After updating to 2.0.1 and call .Any(), I get: The type initializer for 'Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions' threw an exception
Inner exception: Sequence contains no matching element
at System.Linq.Enumerable.Single[TSource] (System.Collections.Generic.IEnumerable1[T] source, System.Func2[T,TResult] predicate) [0x0006b] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.3.0.47/src/mono/external/corefx/src/System.Linq/src/System/Linq/Single.cs:79
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.GetMethod (System.String name, System.Int32 parameterCount, System.Func`2[T,TResult] predicate) [0x00029] in :0
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions..cctor () [0x00011] in :0

@divega
Copy link
Author

divega commented Feb 5, 2018

From @Deepakroy on November 22, 2017 9:50

I have the same issue, is there any solution?

@divega
Copy link
Author

divega commented Feb 5, 2018

From @eusebiu on November 22, 2017 11:5

I found an workaround (as it was blocking me to release the app), inspired by @rob2212 - use linkskip.
Set Configuration to Release, Link Framework SDK only and add these in mtouch arguments:

--linkskip=Microsoft.EntityFrameworkCore --linkskip=Microsoft.EntityFrameworkCore.Relational --linkskip=Microsoft.EntityFrameworkCore.Sqlite --linkskip=Remotion.Linq --linkskip=Microsoft.Data.Sqlite.Core --linkskip=Microsoft.EntityFrameworkCore.Sqlite.Core --linkskip=Microsoft.Extensions.DependencyInjection.Abstractions --linkskip=Microsoft.Extensions.DependencyInjection --linkskip=Microsoft.Extensions.Logging.Abstractions --linkskip=Microsoft.Extensions.Logging --linkskip=Microsoft.Extensions.Caching.Abstractions --linkskip=Microsoft.Extensions.Caching.Memory --linkskip=Microsoft.Extensions.Options --linkskip=Microsoft.Extensions.Primitives --linkskip=System.Reflection --linkskip=System.Reflection.Primitives --linkskip=System.Linq --linkskip=System.Linq.Expressions --linkskip=System.Linq.Queryable

I don't know if all are needed, but I started with EFCore dependencies and added them until it started to work.

FYI - @NPadrutt, @ajcvickers, @divega

@divega
Copy link
Author

divega commented Feb 5, 2018

From @NPadrutt on November 22, 2017 12:49

@eusebiu nice, so far it seems to work! thank you very much! :)

@divega
Copy link
Author

divega commented Feb 5, 2018

From @evertonutfpr on January 18, 2018 17:5

Any news on this? Thanks!

@divega
Copy link
Author

divega commented Feb 5, 2018

From @shanhongyue on February 4, 2018 9:26

I did not encounter this problem in the iPhone X simulator, but encountered in my real iPhone X machine, which was very interesting.

@GeniusLead
Copy link

Tried various options mentioned above with linkskip still no luck finally ended up converting datatype datetime? to string also double? To string then everything worked.

@spouliot spouliot added question The issue is a question iOS Issues affecting Xamarin.iOS labels Feb 6, 2018
@spouliot
Copy link
Contributor

spouliot commented Feb 6, 2018

EntityFrameworkCore uses quite a bit of reflection which has a few drawbacks: performance (it's slower) and hiding code usage from static analysis tools.

The later is the reason why, when the linker is enabled (default for device builds), you run into issues at runtime. The linker cannot see everything that's required, because there's no hints from the library to help it, so code used only thru reflection is removed.

The attached sample works for me when when I add this line:

[assembly: Preserve (typeof (System.Linq.Queryable), AllMembers = true)]

to the Main.cs file of the main project. It merely tells the linker that all members of System.Linq.Queryable should be preserved even if static analysis does not see them used by any code.

Now this is not optimal (but better than all the --linkskip above) since there's likely extra code being preserved (and not used, even by reflection). However it does preserve the methods that EntityFrameworkQueryableExtensions requires (which means no exception at runtime).

Note that there might be other places where reflection is used on BCL types so YMMV for your full application.

This is a workaround for consumers of the EntityFrameworkCore. The right fix would be for EntityFrameworkCore to provide all the required hints to the linker (as part of the assembly) since the library authors are the best placed to know the reflection usage made by their code.

@Lapinou42
Copy link

Lapinou42 commented Feb 15, 2019

Hey, I get it working by create a file in my iOS project : Linkers.xml, and add this inside :

<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="mscorlib">
    <type fullname="System.DateTime" preserve="methods" />
  </assembly>
</linker>

Don't forget to change the build action for this file by right clicking on it => Build action => Linker description.

Here is my complete file that take care of EF Core :

<?xml version="1.0" encoding="utf-8"?>
<linker>
    <assembly fullname="mscorlib">
        <type fullname="System.String">
            <method name="Compare">
            </method>
            <method name="CompareTo">
            </method>
            <method name="ToUpper">
            </method>
            <method name="ToLower">
            </method>
        </type>
        <type fullname="System.DateTime" preserve="methods" />
    </assembly>
    <assembly fullname="System.Core">
        <type fullname="System.Linq.Expressions.Expression`1">
        </type>
        <type fullname="System.Linq.Queryable">
        </type>
    </assembly>
</linker>

Hope that can help someone :)

@AmirMahdiNassiri
Copy link

Thanks to all of you guys for listing the workarounds.

For me, the only thing that worked was adding the following line at the beginning of my Main.cs:

[assembly: Preserve (typeof (System.Linq.Queryable), AllMembers = true)]

No additional mtouch arguments needed to be set. In fact, I tried adding

--linkskip=System.Linq.Queryable

but there was no hope! Note that I have set my linker behavior to "Link framework SDKs only" as well.

By the way, I was getting "Sequence contains no matching element" exception on the physical device when calling FirstOrDefault() !!! Just imagine that!

Thank you so much @spouliot

@spouliot
Copy link
Contributor

@AmirMahdiNassiri --linkskip=... works only on assemblies (not on types or namespaces). That's why it did not work, it would have needed to be --linkskip=System.Core

In any case the use of the attribute is much easier as you found out :)

@AmirMahdiNassiri
Copy link

@spouliot Oh I see. Thank you so much for sharing your knowledge :)

@cjorgens79
Copy link

@spouliot - Is this issue still actually being looked at by the Xamarin team? It is now more than two years later and this issue still exists even with the current releases of Xamarin and EFCore. It seems like this issue should be addressed by the Xamarin team properly, rather than just leaving it to developers to run into obscure problems with EFCore when running on physical iOS devices and then wasting a heap of time trying to figure out what is going on and then eventually stumbling across this post.

Am i missing something and this is really not as big an issue as it seems to be to me? I would have thought the majority of people using EFCore would be using Linq as well.

@SofiyaDSRC
Copy link

@spouliot - Is this issue still actually being looked at by the Xamarin team? It is now more than two years later and this issue still exists even with the current releases of Xamarin and EFCore. It seems like this issue should be addressed by the Xamarin team properly, rather than just leaving it to developers to run into obscure problems with EFCore when running on physical iOS devices and then wasting a heap of time trying to figure out what is going on and then eventually stumbling across this post.

Am i missing something and this is really not as big an issue as it seems to be to me? I would have thought the majority of people using EFCore would be using Linq as well.

Try with @Lapinou42 its worked for me

@cjorgens79
Copy link

Try with @Lapinou42 its worked for me

Thanks, yeah that was the option that I ended up using successfully. My post was more about why this is even still necessary 2 years later and if anything is planned to resolve it to save other developers the hassles associated with this issue in the future.

@21r8390
Copy link

21r8390 commented Oct 13, 2021

As of 2021: This error still exists in exactly the same way. After searching for a solution for three weeks, I found out that Don't Link fixes this error.

Is there a disadvantage if I omit the linking?
The downside of this is that SensorKit and other junk is not removed. So do not do it!

@ghost ghost locked as resolved and limited conversation to collaborators May 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
iOS Issues affecting Xamarin.iOS question The issue is a question
Projects
None yet
Development

No branches or pull requests

8 participants