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

Add-Migration error: The key {'TempId'} contains properties in shadow state and is referenced by a relationship #5984

Closed
saf-itpro opened this issue Jul 5, 2016 · 3 comments

Comments

@saf-itpro
Copy link

saf-itpro commented Jul 5, 2016

In my following Model if I have the following the Add-Migration command works fine but if I replace datatype of StateName from string to List<SelectListItem> I get the error shown below. I'm using latest ASP.NET Core 1.0 and VS2015-Update 3 on win 8.1. I've just added the following class in the Model of this MSDN tutorial:

public class State
    {
        public int StateId { get; set; }
        public string StateCode { get; set; }
        public string StateName { set; get; } //Add-Migration works but does NOT work if datatype string is replaced with `List<SelectListItem>` 
    }

Error:

[System.InvalidOperationException: The key {'TempId'} contains properties in shadow state and is referenced by a relationship from 'SelectListGroup' to 'SelectListItem.Group'. Configure a non-shadow principal key for this relationship. at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.KeyConvention.Apply(InternalModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelBuilt(InternalModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator) at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory) at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel() at Microsoft.EntityFrameworkCore.Internal.LazyRef1.get_Value()
at Microsoft.Extensions.DependencyInjection.ServiceProvider.ScopedCallSite.Invoke(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.TransientCallSite.Invoke(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite.Invoke(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.TransientCallSite.Invoke(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.EntityFrameworkCore.Design.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Tools.Cli.MigrationsAddCommand.Execute(CommonOptions commonOptions, String name, String outputDir, String context, String environment, Action1 reporter) at Microsoft.EntityFrameworkCore.Tools.Cli.MigrationsAddCommand.<>c__DisplayClass0_0.<Configure>b__0() at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args) at Microsoft.EntityFrameworkCore.Tools.Cli.Program.Main(String[] args) The key {'TempId'} contains properties in shadow state and is referenced by a relationship from 'SelectListGroup' to 'SelectListItem.Group'. Configure a non-shadow principal key for this relationship. ](url)

@Bartmax
Copy link

Bartmax commented Jul 6, 2016

You are trying to add SelectListItem to your model, that's not how it's supposed to work.

The error is because it can't create a shadow property with a key to the parent. (SelectListItem has string and your State Id is int)

Maybe you can make it somehow work by adding a key explicit using Fluent API. Still, adding a SelectList entity (class owned by MVC) into your database model is not a good idea.

disclaimer: I'm not very familiar with EF, so take everything said with a grain of salt.

@smitpatel
Copy link
Member

When you include navigation of type List<SelectListItem> that will bring SelectListItem as entity type in model. And all other types referenced by properties in it will be also brought in the model (recursively). See https://ef.readthedocs.io/en/latest/modeling/included-types.html#id2 to know how conventions discover types through navigations.
Every entity type must have a non-shadow primary key defined on them and every relationship must be pointing to a non-shadow key. Since those classes discovered by conventions may not have a property named Id, shadow keys are created temporarily which are not replaced with non-shadow keys hence eventually it throws exception like above.
As @Bartmax said, it is really bad idea to bring in types which are not domain classes because you cannot be sure of their shapes as a proper entity type and related entity types they may discover further.

@rowanmiller
Copy link
Contributor

Given that SelectListItem doesn't have a property that can be used as a primary key, the best option would be to create an entity class that wraps SelectListItem and captures that data that needs to be saved/queried. In the future, something like our Flexible Mapping feature (#240) would make reading/writing from/to a SelectListItem property a possibility.

@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
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

5 participants