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

Multiple properties with default implementation in an interface, applied to an abstract hierarchy, causes scaffolding to fail #23261

Closed
vslee opened this issue Nov 10, 2020 · 3 comments

Comments

@vslee
Copy link

vslee commented Nov 10, 2020

Consider an interface which uses the default implementation feature on some temporary variables. Those temporary variables are marked with the [NotMapped] attribute. If too many of those variables are used, and the interface is applied to an inheritance hierarchy which contains an abstract ancestor, then the model is unable to scaffold. Please see the code example below:

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;

namespace InterfaceOnDerived
{
    class Program
    {
        static void Main(string[] args) { }
    }
    public class BloggingContext : DbContext
    {
        public DbSet<BlogPost> BlogPosts { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(
                @"Server=(localdb)\mssqllocaldb;Database=Blogging;Integrated Security=True");
        }
    }

	public interface ITitle
	{
		// commenting out one or more of these NotMapped properties fixes the problem
		[NotMapped] public string Temp1 => "abcd";
		[NotMapped] public string Temp2 => "abcd";
		[NotMapped] public string Temp3 => "abcd";
		[NotMapped] public string Temp4 => "abcd";
		[NotMapped] public string Temp5 => "abcd";

		public string Title { get; set; } // commenting out this property also fixes the problem
	}

	public abstract class Post : ITitle // making this non-abstract also fixes the problem
	{
		[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
		public int Id { get; set; }

		public string Title { get; set; }

	}
	public class BlogPost : Post { }
}
PM> Add-Migration MyFirstMigration -v
Using project 'InterfaceOnDerived'.
Using startup project 'InterfaceOnDerived'.
Build started...
Build succeeded.
C:\Program Files\dotnet\dotnet.exe exec --depsfile "G:\Google Drive\TestProjects\InterfaceOnDerived\InterfaceOnDerived\bin\Debug\net5.0\InterfaceOnDerived.deps.json" --additionalprobingpath C:\Users\vslee\.nuget\packages --runtimeconfig "G:\Google Drive\TestProjects\InterfaceOnDerived\InterfaceOnDerived\bin\Debug\net5.0\InterfaceOnDerived.runtimeconfig.json" C:\Users\vslee\.nuget\packages\microsoft.entityframeworkcore.tools\5.0.0\tools\netcoreapp2.0\any\ef.dll migrations add MyFirstMigration --json --verbose --no-color --prefix-output --assembly "G:\Google Drive\TestProjects\InterfaceOnDerived\InterfaceOnDerived\bin\Debug\net5.0\InterfaceOnDerived.dll" --startup-assembly "G:\Google Drive\TestProjects\InterfaceOnDerived\InterfaceOnDerived\bin\Debug\net5.0\InterfaceOnDerived.dll" --project-dir "G:\Google Drive\TestProjects\InterfaceOnDerived\InterfaceOnDerived\\" --language C# --working-dir "G:\Google Drive\TestProjects\InterfaceOnDerived" --root-namespace InterfaceOnDerived
Using assembly 'InterfaceOnDerived'.
Using startup assembly 'InterfaceOnDerived'.
Using application base 'G:\Google Drive\TestProjects\InterfaceOnDerived\InterfaceOnDerived\bin\Debug\net5.0'.
Using working directory 'G:\Google Drive\TestProjects\InterfaceOnDerived\InterfaceOnDerived'.
Using root namespace 'InterfaceOnDerived'.
Using project directory 'G:\Google Drive\TestProjects\InterfaceOnDerived\InterfaceOnDerived\'.
Remaining arguments: .
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider in assembly 'InterfaceOnDerived'...
Finding Microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Finding DbContext classes in the project...
Found DbContext 'BloggingContext'.
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type 'BloggingContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
 ---> System.TypeLoadException: Method 'set_Title' in type 'InterfaceOnDerived.BlogPost' from assembly 'InterfaceOnDerived, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
   at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
   at System.Reflection.RuntimeMethodInfo.get_Signature()
   at System.Reflection.RuntimeMethodInfo.FetchNonReturnParameters()
   at System.Reflection.RuntimeMethodInfo.GetParametersNoCopy()
   at System.Reflection.RuntimePropertyInfo.GetIndexParametersNoCopy()
   at System.Reflection.RuntimePropertyInfo.GetIndexParameters()
   at Microsoft.EntityFrameworkCore.Internal.DbSetFinder.<>c.<FindSetsNonCached>b__2_0(PropertyInfo p)
   at System.Linq.Enumerable.WhereArrayIterator`1.ToArray()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.GetEnumerator()+MoveNext()
   at System.Linq.Enumerable.SelectIPartitionIterator`2.LazyToArray()
   at System.Linq.Enumerable.SelectIPartitionIterator`2.ToArray()
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Microsoft.EntityFrameworkCore.Internal.DbSetFinder.FindSetsNonCached(Type contextType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Internal.DbSetFinder.FindSets(Type contextType)
   at Microsoft.EntityFrameworkCore.Internal.DbSetInitializer.InitializeSets(DbContext context)
   at Microsoft.EntityFrameworkCore.DbContext..ctor(DbContextOptions options)
   at Microsoft.EntityFrameworkCore.DbContext..ctor()
   at InterfaceOnDerived.BloggingContext..ctor()
--- End of stack trace from previous location ---
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_4.<FindContextTypes>b__13()
   --- End of inner exception stack trace ---
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_4.<FindContextTypes>b__13()
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Unable to create an object of type 'BloggingContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

EF Core version: 5.0 RTM
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 5.0 RTM
Operating system: Windows 10 Pro 20H2
IDE: Visual Studio 2019 16.8.0

@vslee vslee changed the title Multiple NotMapped properties in an interface, applied to an abstract hierarchy, causes scaffolding to fail Multiple properties with default implementation in an interface, applied to an abstract hierarchy, causes scaffolding to fail Nov 10, 2020
@vslee
Copy link
Author

vslee commented Nov 10, 2020

I also tried removing only the [NotMapped] attributes but leaving the default properties there, but that does not fix the problem.
Doing any of the three things in the code comments does, however.

@smitpatel
Copy link
Contributor

Error is not related to EF Core at all. It happens without EF Core too.
Repro

using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;

namespace BugInReflection
{
    class Program
    {
        static void Main(string[] args)
        {
            var p = typeof(Program).GetProperties().Select(e => e.GetIndexParameters()).ToList();
        }

        public BlogPost BlogPost { get; set; }
    }

    public interface ITitle
    {
        // commenting out one or more of these NotMapped properties fixes the problem
        [NotMapped] public string Temp1 => "abcd";
        [NotMapped] public string Temp2 => "abcd";
        [NotMapped] public string Temp3 => "abcd";
        [NotMapped] public string Temp4 => "abcd";
        [NotMapped] public string Temp5 => "abcd";

        public string Title { get; set; } // commenting out this property also fixes the problem
    }

    public abstract class Post : ITitle // making this non-abstract also fixes the problem
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        public string Title { get; set; }

    }
    public class BlogPost : Post { }
}

@vslee
Copy link
Author

vslee commented Nov 11, 2020

Thank you for the quick response and debugging to figure out that the bug is external to EF Core. I should have dug deeper myself. I have now filed a bug in the appropriate repo dotnet/runtime#44533.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants