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

Collection Navigation property without Setter error on UWP #19535

Closed
YZahringer opened this issue Jan 9, 2020 · 14 comments
Closed

Collection Navigation property without Setter error on UWP #19535

YZahringer opened this issue Jan 9, 2020 · 14 comments
Labels
area-platform closed-out-of-scope This is not something that will be fixed/implemented and the issue is closed. customer-reported punted-for-5.0

Comments

@YZahringer
Copy link

YZahringer commented Jan 9, 2020

On UWP, when a navigation property of type ICollection does not have a setter and is auto-initialized, an error occurs when retrieving the object or when adding it:

Value cannot be null.
Parameter name: frameworkName
   at Microsoft.EntityFrameworkCore.Metadata.Internal.ClrCollectionAccessorFactory.Create(INavigation navigation)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Navigation.<>c.<get_CollectionAccessor>b__21_0(Navigation n)
   at Microsoft.EntityFrameworkCore.Internal.NonCapturingLazyInitializer.EnsureInitialized[TParam,TValue](TValue& target, TParam param, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Navigation.get_CollectionAccessor()
   at Microsoft.EntityFrameworkCore.NavigationExtensions.GetCollectionAccessor(INavigation navigation)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.CustomShaperCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
   at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)
   at System.Linq.Expressions.ConditionalExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
   at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, LambdaExpression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.SingleOrDefaultAsync[TSource](IQueryable`1 source, Expression`1 predicate, CancellationToken cancellationToken)

It works correctly in .NET Core 3.1 web app and it worked correctly in 2.2 on both platforms. UWP uses .NET Standard 2.0, could this be the cause of a different behavior compared to .NET Core 3.1?

Steps to reproduce

This test pass on netcoreapp3.1 but fails on Unit Test App (UWP)

[TestClass]
public class UniversalAppTests
{
    [TestMethod]
    public void CollectionNavigationPropertyWithoutSetter()
    {
        var options = new DbContextOptionsBuilder<TestContext>()
            .UseInMemoryDatabase(databaseName: "Add_writes_to_database")
            .Options;

        using (var context = new TestContext(options))
        {
            // If you remove the include or add the setter to the navigation property, the error is not generated
            context.WithCollections.Include(c => c.Simples).ToArray();

            // The error is generated with any operation on an object that does not have a setter on the collection property navigation
            context.WithCollections.Add(new WithCollection());
        }
    }
}

public class TestContext : DbContext
{
    public TestContext(DbContextOptions<TestContext> options)
        : base(options)
    {

    }

    public DbSet<WithCollection> WithCollections { get; set; }
    public DbSet<Simple> Simples { get; set; }
}

public class WithCollection
{
    public int Id { get; set; }

    // Add setter to fix error on UWP
    public ICollection<Simple> Simples { get; /*set;*/ } = new HashSet<Simple>();
}

public class Simple
{
    public int Id { get; set; }
    public int WithCollectionId { get; set; }
}

Further technical details

EF Core version: 3.1
Database provider: Microsoft.EntityFrameworkCore.Sqlite or InMemory
Target framework: .NET Standard 2.0
Operating system: Windows 10.0.18362
IDE: Visual Studio 2019 16.4.2

@adamhewitt627
Copy link
Member

I happened to just update a few minutes ago and hit this same issue.

@Mys73rion
Copy link

We just updated our application to EF Core 3.1 and faced the same issue.
The error message is, how to say, completely confusing and just a kind of blabla. Would be nice if the message could help you to find the problem.
We hat to introduce multiple nonsense setters which is kind of stupid.

@ajcvickers
Copy link
Member

@bricelam @AndriySvyryd Do either of you have a machine already setup for UWP development where you could test this?

@ajcvickers
Copy link
Member

Notes from investigation: This appears to be a bug in delegate compilation for setting read-only fields. I was able to reproduce using EF, but so far my attempts to repro outside of EF have failed--It may be that the offending code has to be compiled as a .NET Standard 2.0 library, like EF is.

@YZahringer @adamhewitt627 @Mys73rion A couple of workarounds:

  • Don't have properties with read-only fields. For example, add a private setter to the property so that the compiler-generated field is not read-only.
  • Use modelBuilder.UsePropertyAccessMode(PropertyAccessMode.Property); to force EF to read and write to properties rather than fields.

@CrossBound
Copy link

We ran into this error when running in .Net Framework 4.8 ASP.NET Web Forms application.
Adding private setters resolved the issue.

@YZahringer
Copy link
Author

Related to #19588

@YZahringer
Copy link
Author

Since EF Core 5.0 no longer supports .NET Standard 2.0, this is still relevant?

Currently UWP does not support .NET Standard 2.1, so how do I use EF Core 5.0?
UWP is still supported by EF Core 5.0?

@ajcvickers
Copy link
Member

@YZahringer We are watching with interest how the various U.I. platforms develop. Given all the issues we have had trying to create a good experience for UWP together with internal usage data, we have currently put it on the backburner.

@bricelam
Copy link
Contributor

bricelam commented Nov 9, 2020

@YZahringer What are your plans in general? Will you be converting your apps use WinUI 3 on top of .NET 5/Win32, or do you intend to remain on .NET Native/UWP?

@bricelam
Copy link
Contributor

bricelam commented Nov 9, 2020

Also, are you considering .NET MAUI (the evolution of Xamarin.Forms) as a viable alternative?

@YZahringer
Copy link
Author

@bricelam We mainly use EF Core SQLite on UWP with Xamarin.Forms in multiple cross-platform applications (UWP, Android, iOS). Currently we do not use WinUI "natively", but Xamarin.Forms uses WinUI 2.4 to render on UWP.

WinUI 3 is still in preview and maybe supported by Xamarin.Forms 5 !11955 or reported to MAUI.

The future with .NET MAUI and .NET 6 is very interesting, but it won't be before the end of next year. So in the meantime, it would be useful to find a solution to use the latest version of EF Core on cross-platform apps with Xamarin.Forms 😃

@YZahringer
Copy link
Author

Multitarget netstandard2.0;netstandard2.1 until net6.0 release could be considered? related to #18141 (comment)

@ajcvickers ajcvickers added propose-close closed-out-of-scope This is not something that will be fixed/implemented and the issue is closed. and removed type-bug blocked area-external propose-close area-change-tracking labels Nov 10, 2021
@ajcvickers ajcvickers removed this from the Backlog milestone Nov 10, 2021
@ajcvickers ajcvickers removed their assignment Nov 10, 2021
@ajcvickers
Copy link
Member

Note from triage: UWP is not supported in .NET 6.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
@andorremus
Copy link

Just wanted to put this here in case someone else was having this problem.

This was happening to me as well for a .Net Framework web application, it was really weird because it only happened to one of our clients, the rest were fine. What I ended up finding is that the one that wasn't working didn't have the http runtime target framework set so it was running under .net 4.0, causing it to throw that exception everytime ef core was trying to initialise a collection that was set to readonly.

So the fix was changing the http runtime to the one we were using (4.7.2) and this got sorted.

<httpRuntime requestValidationMode="2.0" targetFramework="4.7.2" executionTimeout="600" />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-platform closed-out-of-scope This is not something that will be fixed/implemented and the issue is closed. customer-reported punted-for-5.0
Projects
None yet
Development

No branches or pull requests

8 participants