错误:实体类型需要主键

我想扩展这个问题上提出的问题

将列表框绑定到observablecollection

通过赋予它持久化数据的能力。 除了我安装Entity Framework Core之外,结构大致相同,创建了一个DbContext类来保存记录。 我添加了一个按钮将数据集保存到SQL Server。 我没有遇到编译错误但是当我试图将数据保存在数据库中时,我得到了这个运行时exception:

Message =实体类型’Fruit’需要定义主键。

整个例外情况如下

System.InvalidOperationException未处理
的HResult = -2146233079
Message =实体类型’Fruit’需要定义主键。
来源= Microsoft.EntityFrameworkCore
堆栈跟踪:
在Microsoft.EntityFrameworkCore.Internal.ModelValidator.ShowError(String message)
在Microsoft.EntityFrameworkCore.Internal.ModelValidator.EnsureNonNullPrimaryKeys(IModel模型)
在Microsoft.EntityFrameworkCore.Internal.ModelValidator.Validate(IModel模型)
在Microsoft.EntityFrameworkCore.Internal.RelationalModelValidator.Validate(IModel模型)
在Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext上下文,IConventionSetBuilder conventionSetBuilder,IModelValidatorvalidation器)
在Microsoft.EntityFrameworkCore.Infrastructure.ModelSource。 c__DisplayClass14_0.b__0(对象k)
在System.Collections.Concurrent.ConcurrentDictionary 2.GetOrAdd(TKey key, Func 2 valueFactory)
在Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext上下文,IConventionSetBuilder conventionSetBuilder,IModelValidatorvalidation器)
在Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
在Microsoft.EntityFrameworkCore.Internal.LazyRef 1.get_Value()
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServiceCollectionExtensions.c.b__0_6(IServiceProvider p)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactoryService(FactoryService factoryService, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
1.get_Value()
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServiceCollectionExtensions.c.b__0_6(IServiceProvider p)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactoryService(FactoryService factoryService, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
1.get_Value()
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServiceCollectionExtensions.c.b__0_6(IServiceProvider p)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactoryService(FactoryService factoryService, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.VisitCallSite(IServiceCallSite callSite,TArgument参数)
在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,ServiceProvider provider)
在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.VisitCallSite(IServiceCallSite callSite,TArgument参数)
在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,ServiceProvider provider)
在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.c__DisplayClass16_0.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](IInfrastructure
2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.c__DisplayClass16_0.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](IInfrastructure
2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.c__DisplayClass16_0.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](IInfrastructure
1 accessor)
在Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.get_StateManager()
在Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges()
在Microsoft.EntityFrameworkCore.DbContext.TryDetectChanges()
在Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
在Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
在Fruits:MainWindow.SaveFruitCommandBinding_Executed(Object sender,ExecutedRoutedEventArgs e)在D:\ Frank \ Test \ Fruits \ Fruits \ MainWindow.xaml.cs:第50行
在System.Windows.Input.CommandBinding.OnExecuted(Object sender,ExecutedRoutedEventArgs e)
在System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender,ExecutedRoutedEventArgs e,CommandBinding commandBinding)
在System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings,Object sender,RoutedEventArgs e,ICommand command,Boolean execute)
在System.Windows.Input.CommandManager.FindCommandBinding(对象发送者,RoutedEventArgs e,ICommand命令,布尔执行)
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 at系统中System.Windows.EventRoute.InvokeHandlersImpl(Object source,RoutedEventArgs args,Boolean reRaised)的System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target,RoutedEventArgs routedEventArgs)中的System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler,Object target)。 System.Windows.UIElement.RaiseEvent(RoutedEventArgs args,布尔值受信任)的System.Windows.Input.RoutedCommand.ExecuteImpl(Object参数,IInputElement target,Boolean userInitiated)中的Windows.UIElement.RaiseEventImpl(DependencyObject sender,RoutedEventArgs args)。 MS.Internal.Commands.CommandHel中的Windows.Input.RoutedCommand.ExecuteCore(Object parameter,IInputElement target,Boolean userInitiated) System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs)中的System.Windows.Controls.Button.OnClick()处的System.Windows.Controls.Primitives.ButtonBase.OnClick()中的pers.CriticalExecuteCommandSource(ICommandSource commandSource,Boolean userInitiated) e)位于System.Windows.RindtedEventArgs.InvokeHandler(委托处理程序,对象目标)的System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler,Object genericTarget)中的System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender,MouseButtonEventArgs e)at at在System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender,RoutedEventArgs args,RoutedEvent newEvent)的System.Windows.EventRoute.InvokeHandlersImpl(Object source,RoutedEventArgs args,Boolean reRaised)中的System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target,RoutedEventArgs routedEventArgs) System.Windows.Input.MouseButt上的System.Windows.UIElement.OnMouseUpThunk(Object sender,MouseButtonEventArgs e) System.Windows.EventRoute.InvokeHandlersImpl(Object)上的System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target,RoutedEventArgs routedEventArgs)上的System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler,Object target)中的onEventArgs.InvokeEventHandler(Delegate genericHandler,Object genericTarget)在System.Windows.Uindlement.RaiseEvent(RoutedEventArgs args,布尔值受信任)的System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)的System.Windows.UIElement.RaiseEventImpl(DependencyObject sender,RoutedEventArgs args)中的source,RoutedEventArgs args,Boolean reRaised)处于System.Windows.Inputop.HwndMouseInputProvider.ReportInput中System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)的System.Windows.Input.InputManager.ProcessInput(InputEventArgs输入)中的System.Windows.Input.InputManager.ProcessStagingArea() System.Windows.Interop.H上的(IntPtr hwnd,InputMode模式,Int32时间戳,RawMouseActions操作,Int32 x,Int32 y,Int32轮) 在MS.Win32的System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,Boolean&handling)中的wndMouseInputProvider.FilterMessage(IntPtr hwnd,WindowMessage msg,IntPtr wParam,IntPtr lParam,Boolean&handling)。在System.Windows.Threading.ExceptionWrapper.InternalRealCall的MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)中的HwndWrapper.WndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,Boolean&handling)(委托回调,Object args,Int32 numArgs )在System.Windows.Threading.Dispatcher.LegacyInvokeImpl的System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source,Delegate callback,Object args,Int32 numArgs,Delegate catchHandler)中(DispatcherPriority优先级,TimeSpan超时,Delegate方法,Object args,位于System.Windows.Threading.Dispatch的MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG&msg)的MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam)上的Int32 numArgs) System.Windows上的System.Windows.Application.RunInternal(窗口窗口)中的System.Windows.Application.RunDispatcher(Object ignore)处的System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame框架)中的er.PushFrameImpl(DispatcherFrame框架)。 System.AppDomain.ExecuteAssembly(String assemblyFile,证据assemblySecurity,String [] args)位于System.Threading.Thread上的Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()处于System.Threading.TereadStart_Context(Object状态),执行文件执行上下文(ExecutionContext executionContext,ContextCallback回调,对象状态, System.Threading.ExecutionContext.Run上的System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,Object状态,Boolean preserveSyncCtx)中的Boolean preserveSyncCtx(ExecutionContext exec) System.Threading.ThreadHelper.ThreadStart()中的utionContext,ContextCallback回调,对象状态InnerException:

这是更新的类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 } } 

更新的MainWindows xaml(添加保存按钮)

            Selected Fruit Only        <!---->     

和我在mainwindows后面的代码(添加处理程序)

 using Fruits.ViewModels; using System; using System.Windows; using System.Windows.Input; namespace Fruits { ///  /// Interaction logic for MainWindow.xaml ///  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; } } } 

我新添加的dbContext:

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

其他类保持不变,但无论如何我列出了它们:

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(); } 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 _fruits; public ObservableCollection 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中

                              

我项目的结构

在此处输入图像描述

我在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] 

请告知为什么消息说它确实存在时没有主键

此exception消息并不意味着它需要在数据库中定义主键,这意味着它需要在您的类中定义主键。

虽然你试图这样做:

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

这没有任何效果,因为entity framework忽略只读属性。 它必须:当它从数据库中检索Fruits记录时,它构造一个Fruit对象,然后为每个映射的属性调用属性setter。 这对于只读属性永远不会起作用。

您需要Entity Framework才能设置ID的值。 这意味着该物业需要一个二传手。

我带着类似的错误来到这里:

System.InvalidOperationException:’实体类型’MyType’需要定义主键。

在读完hvd的回答之后,意识到我只是忘了让我的关键财产“公开”。 这个..

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

应该是这个..

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