Error: the entity type requires a primary key

C#Entity Framework-Core

C# Problem Overview


I would like to expand the question asked on this thread

Binding listbox to observablecollection

by giving it an ability to persistent the data. The structure is mostly the same except I installed Entity Framework Core, created a DbContext class to hold the records. I added a button to save the dataset to SQL Server. I did not encounter the compiling error but when I attempted to save the data in the database I got this run time exception:

> Message=The entity type 'Fruit' requires a primary key to be defined.

The whole exception in its entirety is listed below

> System.InvalidOperationException was unhandled
> HResult=-2146233079
> Message=The entity type 'Fruit' requires a primary key to be defined.
> Source=Microsoft.EntityFrameworkCore
> StackTrace:
> at Microsoft.EntityFrameworkCore.Internal.ModelValidator.ShowError(String message)
> at Microsoft.EntityFrameworkCore.Internal.ModelValidator.EnsureNonNullPrimaryKeys(IModel model)
> 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 Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass14_0.b__0(Object k)
> at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory)
> at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
> at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
> at Microsoft.EntityFrameworkCore.Internal.LazyRef1.get_Value() > at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model() > at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServiceCollectionExtensions.<>c.<AddEntityFramework>b__0_6(IServiceProvider p) > at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactoryService(FactoryService factoryService, ServiceProvider provider) > at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
> at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
> at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument) > at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider) > at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
> at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
> at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument) > at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider) > at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) > at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) > at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure1 accessor)
> at Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.get_StateManager()
> at Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges()
> at Microsoft.EntityFrameworkCore.DbContext.TryDetectChanges()
> at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
> at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
> at Fruits.MainWindow.SaveFruitCommandBinding_Executed(Object sender, ExecutedRoutedEventArgs e) in D:\Frank\Test\Fruits\Fruits\MainWindow.xaml.cs:line 50
> at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
> at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
> at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
> at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
> at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e) at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e) at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated) at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated) at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated) at System.Windows.Controls.Primitives.ButtonBase.OnClick() at System.Windows.Controls.Button.OnClick() at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e) at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e) at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) at System.Windows.Application.RunDispatcher(Object ignore) at System.Windows.Application.RunInternal(Window window) at System.Windows.Application.Run(Window window) at System.Windows.Application.Run() at Fruits.App.Main() at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException:

This is the updated class Fruit:

namespace Fruits.ViewModels
{
	[Table("Fruits")]
	public  class Fruit : ViewModelBase
	{
		#region Constractor
		public Fruit()
		{
		}
		public Fruit(string name, String clrString)
		{
			FruitName = name;
			//  Parse colors like so: (Color)ColorConverter.ConvertFromString(clrString);
			FruitColor = clrString;
			_id = Guid.NewGuid();
		}
		public Fruit(string name, Color clr)
		{
			FruitName = name;
			FruitColor = clr.ToString();
			_id = Guid.NewGuid();
		}

		#endregion

		#region Properties
		private Guid _id;
		[Key]
		public Guid ID
		{
			get { return _id; }
		}

		#region FruitName
		private string _fruitname;
		public string FruitName
		{
			get
			{
				return _fruitname;
			}
			set
			{
				if (_fruitname != value)
				{
					_fruitname = value;
					OnPropertyChanged("FruitName");
				}
			}
		}
		#endregion

		#region FruitColor
		private String _fruitcolor;
		public String FruitColor
		{
			get
			{
				return _fruitcolor;
			}
			set
			{
				if (_fruitcolor != value)
				{
					_fruitcolor = value;
					OnPropertyChanged("FruitColor");
				}
			}
		}
		#endregion

		#region Selected Property
		private bool _isSelected = true;
		//  NOTE: I renamed this property
		public bool IsSelected
		{
			get
			{
				return _isSelected;
			}
			set
			{
				if (_isSelected != value)
				{
					_isSelected = value;
					OnPropertyChanged("IsSelected");
				}
			}
		}
		#endregion

		#endregion
	}
}

The updated MainWindows xaml (to add a save button)

<Window x:Class="Fruits.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Fruits"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
	<Window.Resources>
		<RoutedCommand x:Key="AddFruit" />
		<RoutedCommand x:Key='SaveFruit' />
	</Window.Resources>
	<Window.CommandBindings>
		<CommandBinding Command='{StaticResource AddFruit}'
										Executed='AddFruitCommandBinding_Executed'
										CanExecute='AddFruitCommandBinding_CanExecute' />
		<CommandBinding Command='{StaticResource SaveFruit}'
										Executed='SaveFruitCommandBinding_Executed'
										CanExecute='SaveFruitCommandBinding_CanExecute' />
	</Window.CommandBindings>
	<Grid>
		<StackPanel Orientation='Vertical'
								Margin='10'>
			<CheckBox IsChecked="{Binding ShowSelectedFruitOnly}">Selected Fruit Only</CheckBox>
			<ListBox x:Name='MyList'
							 ItemsSource="{Binding FruitsView}"
							 ItemTemplate='{StaticResource FruitTemp}' />
			<StackPanel Orientation="Horizontal"
									Margin="0,10,0,0">
				<Label Width="100">New Name:</Label>
				<TextBox Width="200"
								 Text="{Binding NewFruitName, Mode=TwoWay }" 
								 />
			</StackPanel>
			<StackPanel Orientation="Horizontal"
									Margin="0,10,0,0">
				<Label Width="100">New Color:</Label>
				<!--<TextBox Width="200"
								 Text="{Binding NewFruitColor, UpdateSourceTrigger=PropertyChanged}" />-->
				<TextBox Width="200"
								 Text="{Binding NewFruitColor, Mode=TwoWay }" />

				<ContentControl Style="{StaticResource ColorSwatch}"
												Margin="2"
												VerticalAlignment="Center"
												Content="{Binding NewFruitColor}" />
			</StackPanel>
			<StackPanel Orientation='Horizontal'>
			<Button x:Name='AddFruit'
							Height='auto'
							Width='auto'
							Content='Add New Fruit 2'
							Margin='0,10,0,0'
							Command='{StaticResource AddFruit}' />
				<Button x:Name='SaveFruit'
								Height='auto'
								Width='auto'
								Content='Save Fruit'
								Margin='100,10,0,0'
								Command='{StaticResource SaveFruit}' />
			</StackPanel>
		</StackPanel>
	</Grid>
</Window>

and my code behind the mainwindows (added handler)

using Fruits.ViewModels;
using System;
using System.Windows;
using System.Windows.Input;

namespace Fruits
{
	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window
	{
		public MainWindow()
		{
			InitializeComponent();
			DataContext = new MainViewModel();

			ViewModel.AddNewFruit("Jackfruit", "Yellow");
			ViewModel.AddNewFruit("Watermelon", "ForestGreen");
			ViewModel.AddNewFruit("Apple", "Red");
			ViewModel.AddNewFruit("Banana", "Yellow");
			ViewModel.AddNewFruit("Orange", "DeepSkyBlue");

			//ViewModel.Fruits[0].IsSelected = false;
			//ViewModel.Fruits[1].IsSelected = false;

			ViewModel.FruitsView.Refresh();
		}

		public MainViewModel ViewModel { get { return DataContext as MainViewModel; } }

		private void AddFruitCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			ViewModel.AddNewFruit();
		}

		private void AddFruitCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute =
					ViewModel != null
					&& !String.IsNullOrWhiteSpace(ViewModel.NewFruitName)
					&& !String.IsNullOrWhiteSpace(ViewModel.NewFruitColor)
					;
		}

		private void SaveFruitCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			using (var db=new FruitDbContext())
			{
				db.SaveChanges();
			}
		}

		private void SaveFruitCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = true;
		}
	}
}

My newly added dbContext:

namespace Fruits.ViewModels
{
	public class FruitDbContext:DbContext
	{
		public DbSet<Fruit> Fruits { get; set; }
		protected override void OnConfiguring(DbContextOptionsBuilder optionBuilder)
		{
			optionBuilder.UseSqlServer(@"Server = xxx; Database=Test; Integrated Security = True");
		}
	}
}

Other classes remain unchanged, but I listed them anyway:

ViewModelBase

    namespace Fruits.ViewModels
    {
    	public  class ViewModelBase : INotifyPropertyChanged
    	{
    		public event PropertyChangedEventHandler PropertyChanged;
    		public void OnPropertyChanged(string name)
    		{
    			if (PropertyChanged != null)
    			{
    				PropertyChanged(this, new PropertyChangedEventArgs(name));
    			}
    		}
    	}
    }

ViewModel

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Media;

namespace Fruits.ViewModels
{

	#region MainViewModel Class
	public class MainViewModel : ViewModelBase
	{
		public  MainViewModel()
		{
			Fruits = new ObservableCollection<Fruit>();

		}
		public ICollectionView FruitsView { get; private set; }

		#region ShowSelectedFruitOnly Property
		private bool _showSelectedFruitOnly = true;
		public bool ShowSelectedFruitOnly
		{
			get { return _showSelectedFruitOnly; }
			set
			{
				if (value != _showSelectedFruitOnly)
				{
					_showSelectedFruitOnly = value;
					FruitsView.Refresh();
					OnPropertyChanged("ShowSelectedFruitOnly");
				}
			}
		}
		#endregion ShowSelectedFruitOnly Property

		#region Add Methods
		public void AddNewFruit()
		{
			Fruits.Add(new Fruit(NewFruitName, NewFruitColor));

			NewFruitName = "";
			NewFruitColor = "";
		}
		public void AddNewFruit(string name, string color)
		{
			Fruits.Add(new Fruit(name, color));
		}
		public void AddNewFruit(string name, Color color)
		{
			Fruits.Add(new Fruit(name, color));
		}
		#endregion Add Methods

		#region NewFruitName Property
		private String _newFruitName = default(String);
		public String NewFruitName
		{
			get { return _newFruitName; }
			set
			{
				if (value != _newFruitName)
				{
					_newFruitName = value;
					OnPropertyChanged("NewFruitName");
				}
			}
		}
		#endregion NewFruitName Property

		#region NewFruitColor Property
		private String _newFruitColor = default(String);
		public String NewFruitColor
		{
			get { return _newFruitColor; }
			set
			{
				if (value != _newFruitColor)
				{
					_newFruitColor = value;
					OnPropertyChanged("NewFruitColor");
				}
			}
		}
		#endregion NewFruitColor Property

		#region Fruits Property
		private static ObservableCollection<Fruit> _fruits;
		public ObservableCollection<Fruit> Fruits
		{
			get { return _fruits; }
			private set
			{
				if (value != _fruits)
				{
					_fruits = value;

					FruitsView = CollectionViewSource.GetDefaultView(Fruits);

					FruitsView.Filter = FruitFilterPredicate;
					FruitsView.Refresh();

					OnPropertyChanged("Fruits");
				}
			}
		}
		protected bool FruitFilterPredicate(Object o)
		{
			if (ShowSelectedFruitOnly)
			{
				return (o as Fruit).IsSelected;
			}

			return true;
		}
		#endregion Fruits Property
	}

	#endregion MainViewModel Class
}

App.xaml

<Application x:Class="Fruits.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Fruits"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
		<Style x:Key="ColorSwatch"
					 TargetType="ContentControl">
			<Setter Property="Width"
							Value="24" />
			<Setter Property="Height"
							Value="24" />
			<Setter Property="IsTabStop"
							Value="false" />
			<Setter Property="ContentTemplate">
				<Setter.Value>
					<DataTemplate>
						<Rectangle HorizontalAlignment="Stretch"
											 VerticalAlignment="Stretch"
											 Stroke="Gray"
											 StrokeThickness="1">
							<Rectangle.Fill>
								<SolidColorBrush Color="{Binding}" />
							</Rectangle.Fill>
						</Rectangle>
					</DataTemplate>
				</Setter.Value>
			</Setter>
		</Style>

		<DataTemplate x:Key='FruitTemp'>
			<StackPanel Orientation='Horizontal'
									Margin='5'>
				<TextBlock x:Name='tbName'
									 Text='{Binding FruitName}'
									 Margin='10,0,0,0'
									 Width='100' />
				<TextBlock x:Name='tbColor'
									 Text='{Binding FruitColor}'
									 Margin='10,0,0,0'
									 Width='100' />
				<ContentControl Width="16"
												Height="16"
												Style="{StaticResource ColorSwatch}"
												Content="{Binding FruitColor}" />
				<!-- The problem here was you were trying to bind Checked, an event, 
                instead if IsChecked, a bool? property. 
                -->
				<CheckBox x:Name='cbSelected'
									Content='Selected'
									Margin='10,0,0,0'
									IsChecked='{Binding IsSelected}' />
			</StackPanel>
		</DataTemplate>
	</Application.Resources>
</Application>

The structure of my project

enter image description here

My table in SQL Server:

CREATE TABLE [dbo].[Fruits]
(
	[ID] [uniqueidentifier] NOT NULL,
	[FruitName] [nvarchar](50) NULL,
	[FruitColor] [nvarchar](50) NULL,
	[IsSelected] [nvarchar](1) NULL,

     CONSTRAINT [PK_Fruit] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

Please advise why the message said there was no primary key while it does exist

C# Solutions


Solution 1 - C#

This exception message doesn't mean it requires a primary key to be defined in your database, it means it requires a primary key to be defined in your class.

Although you've attempted to do so:

> private Guid _id; > [Key] > public Guid ID > { > get { return _id; } > }

This has no effect, as Entity Framework ignores read-only properties. It has to: when it retrieves a Fruits record from the database, it constructs a Fruit object, and then calls the property setters for each mapped property. That's never going to work for read-only properties.

You need Entity Framework to be able to set the value of ID. This means the property needs to have a setter.

Solution 2 - C#

I came here with similar error:

> System.InvalidOperationException: 'The entity type 'MyType' requires a primary key to be defined.'

After reading answer by hvd, realized I had simply forgotten to make my key property 'public'. This..

namespace MyApp.Models.Schedule
{
    public class MyType
    {
        [Key]
        int Id { get; set; }

        // ...

Should be this..

namespace MyApp.Models.Schedule
{
    public class MyType
    {
        [Key]
        public int Id { get; set; }  // must be public!

        // ...

Solution 3 - C#

I found a bit different cause of the error. It seems like SQLite wants to use correct primary key class property name. So...

Wrong PK name

public class Client
{
  public int SomeFieldName { get; set; }  // It is the ID
  ...
}

Correct PK name

public class Client
{
  public int Id { get; set; }  // It is the ID
  ...
}

public class Client
{
  public int ClientId { get; set; }  // It is the ID
  ...
}

It still posible to use wrong PK name but we have to use [Key] attribute like

public class Client
{
   [Key]
   public int SomeFieldName { get; set; }  // It is the ID
   ...
}

Solution 4 - C#

This worked for me:

using System.ComponentModel.DataAnnotations;

[Key]
public int ID { get; set; }

Solution 5 - C#

Make sure you have the following condition:

  1. Use [key] if your primary key name is not Id or ID.
  2. Use the public keyword.
  3. Primary key should have getter and setter.

Example:

public class MyEntity {
   [key]
   public Guid Id {get; set;}
}

Solution 6 - C#

If you get the error:

> The entity type 'DeviceFlowCodes' requires a primary key to be > defined. If you intended to use a keyless entity type, call 'HasNoKey' > in 'OnModelCreating'. For more information on keyless entity types, > see https://go.microsoft.com/fwlink/?linkid=2141943.

You are probably using a solution with Individual User Accounts and have used protected override void OnModelCreating(ModelBuilder modelBuilder) in ApplicationDbContext.

The error comes from ApiAuthorizationDbContext that has a public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }.

Solve the error by calling base.OnModelCreating(modelBuilder); in protected override void OnModelCreating.

Source:

https://github.com/IdentityServer/IdentityServer4/issues/3169

Solution 7 - C#

Your Id property needs to have a setter. However the setter can be private. The [Key] attribute is not necessary if the property is named "Id" as it will find it through the naming convention where it looks for a key with the name "Id".

public Guid Id { get; }              // Will not work
public Guid Id { get; set; }         // Will work
public Guid Id { get; private set; } // Will also work

Solution 8 - C#

When I used the Scaffold-DbContext command, it didn't include the "[key]" annotation in the model files or the "entity.HasKey(..)" entry in the "modelBuilder.Entity" blocks. My solution was to add a line like this in every "modelBuilder.Entity" block in the *Context.cs file:

entity.HasKey(X => x.Id);

I'm not saying this is better, or even the right way. I'm just saying that it worked for me.

Solution 9 - C#

Yet another reason may be that your entity class has several properties named somhow /.*id/i - so ending with ID case insensitive AND elementary type AND there is no [Key] attribute.

EF will namely try to figure out the PK by itself by looking for elementary typed properties ending in ID.

See my case:

public class MyTest, IMustHaveTenant
{
  public long Id { get; set; }
  public int TenantId { get; set; }
  [MaxLength(32)]
  public virtual string Signum{ get; set; }
  public virtual string ID { get; set; }
  public virtual string ID_Other { get; set; }
}

don't ask - lecacy code. The Id was even inherited, so I could not use [Key] (just simplifying the code here)

But here EF is totally confused.

What helped was using modelbuilder this in DBContext class.

            modelBuilder.Entity<MyTest>(f =>
            {
                f.HasKey(e => e.Id);
                f.HasIndex(e => new { e.TenantId });
                f.HasIndex(e => new { e.TenantId, e.ID_Other });
            });

the index on PK is implicit.

Solution 10 - C#

I happened to have tried everything:

  • made sure the property has a setter
  • tried using the [Key] annotation
  • used a property named "Id" with and without the [Key] annotation.

None of these worked, for a simple reason: my database was unavailable.

Fixing the connection to the database solved the "requires a primary key" issue.

(Weird that it's this error that shows even in that case.)

Solution 11 - C#

> The entity type 'DisplayFormatAttribute' requires a primary key to be > defined.

In my case I figured out the problem was that I used properties like this:

public string LastName { get; set; }  //OK
public string Address { get; set; }   //OK 
public string State { get; set; }     //OK
public int? Zip { get; set; }         //OK
public EmailAddressAttribute Email { get; set; } // NOT OK
public PhoneAttribute PhoneNumber { get; set; }  // NOT OK

Not sure if there is a better way to solve it but I changed the Email and PhoneNumber attribute to a string. Problem solved.

Solution 12 - C#

None of the answers worked until I removed the HasNoKey() method from the entity. Dont forget to remove this from your data context or the [Key] attribute will not fix anything.

Solution 13 - C#

Removed and added back in the table using Scaffold-DbContext and the error went away

Solution 14 - C#

In the DBContext I had this <List> code causing the error:

    public DbSet<List<<Item>> Items { get; set; } = null!;

You can get around it by making another class, I made a class ListItem that has a List<Item> in it and then declare both:

    public DbSet<Item> Items { get; set; } = null!;


    public DbSet<ListItem> ListItems { get; set; } = null!;

Solution 15 - C#

If you're using FluentApi make sure you're applying your configuration class like this:

internal class MyModelConfiguration : IEntityTypeConfiguration<MyModel>
    {
        public void Configure(EntityTypeBuilder<MyModel> builder)
        {
            builder.ToView("MyView", "dbo");
            ...
    
protected void OnModelCreating(ModelBuilder modelBuilder)
        {           
            modelBuilder.ApplyConfiguration(new MyConfiguration());
            ...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1205746View Question on Stackoverflow
Solution 1 - C#user743382View Answer on Stackoverflow
Solution 2 - C#Adam CoxView Answer on Stackoverflow
Solution 3 - C#NoWarView Answer on Stackoverflow
Solution 4 - C#BRUCE WAYNEView Answer on Stackoverflow
Solution 5 - C#A-SharabianiView Answer on Stackoverflow
Solution 6 - C#OgglasView Answer on Stackoverflow
Solution 7 - C#FredView Answer on Stackoverflow
Solution 8 - C#Ted O'ConnorView Answer on Stackoverflow
Solution 9 - C#RobettoView Answer on Stackoverflow
Solution 10 - C#GregordyView Answer on Stackoverflow
Solution 11 - C#user3506View Answer on Stackoverflow
Solution 12 - C#Darth ScitusView Answer on Stackoverflow
Solution 13 - C#tfaView Answer on Stackoverflow
Solution 14 - C#Jeremy ThompsonView Answer on Stackoverflow
Solution 15 - C#Ivan YurchenkoView Answer on Stackoverflow