I have 3 other DbSets in my project that are all working fine. When trying to add a 4th, extremely simple one I am hitting errors with Add-Migration. Note that every time I run Add-Migration I wipe the db completely and delete all prior migrations to start fresh. It claims that it can't find a key and I've tried all possible combinations of defining it - convention, annotation and fluent.
I have tried several variations:
```
public class Region
{
public long Id;
public string Stuff;
}
public class Region
{
[Key]
public long Id;
public string Stuff;
}
public class Region
{
[Key]
public long TheKey;
public string Stuff;
}
`
I've also tried setting the Id or TheKey param in fluent:
modelBuilder.Entity<Region>()
.HasKey(p => p.TheKey);
That gives a different error which also doesn't make sense:
> The properties expression 'p => Convert(p.TheKey)' is not valid. The expression should represent a property access: 't => t.MyProperty'. When specifying multiple properties use an anonymous type: 't => new { t.MyProperty1, t.MyProperty2 }'.
I've also tried renaming the class from Region to TheReg just to see if there is some weird name conflict and the results were the same.
Exception message:
Stack trace:
PM> Add-Migration mig1
System.InvalidOperationException: The entity type 'CloudApi.Models.Region' requires a primary key to be defined. at Microsoft.EntityFrameworkCore.Internal.ModelValidator.ShowError(String message)
at Microsoft.EntityFrameworkCore.Internal.ModelValidator.Validate(IModel model)
at Microsoft.EntityFrameworkCore.Internal.RelationalModelValidator.Validate(IModel model)
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.
at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
at Microsoft.EntityFrameworkCore.Tools.Cli.Program.Main(String[] args)
The entity type 'CloudApi.Models.Region' requires a primary key to be defined.
### Further technical details
project.json:
{
"dependencies": {
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Microsoft.ApplicationInsights.AspNetCore": "1.0.2",
"Microsoft.AspNetCore.Mvc": "1.0.1",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
"Microsoft.NETCore.App": "1.0.1",
"Microsoft.EntityFrameworkCore": "1.0.1",
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
"Microsoft.AspNetCore.Diagnostics": "1.0.0",
"System.IdentityModel.Tokens.Jwt": "5.0.0",
"Microsoft.AspNetCore.Authentication.JwtBearer": "1.0.0",
"Microsoft.AspNetCore.Cors": "1.0.0",
"AWSSDK.CognitoIdentity": "3.3.0.1",
"AWSSDK.CognitoIdentityProvider": "3.3.1.1",
"AWSSDK.Core": "3.3.3",
"SapientGuardian.EntityFrameworkCore.MySql": "7.1.9",
"Microsoft.Extensions.Caching.Memory": "1.0.0",
"AWSSDK.SimpleEmail": "3.3.0.1"
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final",
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
},
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},
"runtimes": {
"win10-x64": { }
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
},
"publishOptions": {
"include": [
"wwwroot",
"Views",
"Areas/**/Views",
"appsettings.json",
"web.config"
]
},
"scripts": {
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
}
}
```
You should use properties rather than fields. By convention EF will only map properties with a getter and setter. In 1.1, you can map to fields if you really want to, but my guess is that you actually want properties anyway?
That was exactly the issue. I don't actually have any use cases where a field vs a property matters in my code, but I didn't make the connection that this was a pre-requisite for EF to work. Thank you very much and sorry to trouble you with something so petty.