gpt4 book ai didi

c# - 错误: the entity type requires a primary key

转载 作者:行者123 更新时间:2023-12-02 10:43:22 25 4
gpt4 key购买 nike

我想扩展在此线程中提出的问题

Binding listbox to observablecollection

赋予其持久数据的能力。结构基本相同,除了我安装了 Entity Framework Core,创建了 DbContext类保存记录。我添加了一个按钮来将数据集保存到 SQL Server。我没有遇到编译错误,但是当我尝试将数据保存到数据库中时,我得到了这个运行时异常:

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

下面列出了整个异常

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()<br/>
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()<br/>
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServiceCollectionExtensions.<>c.<AddEntityFramework>b__0_6(IServiceProvider p)<br/>
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactoryService(FactoryService factoryService, ServiceProvider provider)<br/>
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.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)<br/>
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)<br/>
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.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)<br/>
at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider)<br/>
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)<br/>
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)<br/>
at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure
1 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:

这是更新后的 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(添加保存按钮)

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

以及我在主窗口后面的代码(添加了处理程序)

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;
}
}
}

我新添加的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");
}
}
}

其他类保持不变,但我还是列出了它们:

View 模型库

    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
}

应用程序.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>

我的项目的结构

enter image description here

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

请说明为什么消息说没有主键,而主键确实存在

最佳答案

此异常消息并不意味着它需要在您的数据库中定义主键,而是意味着它需要在您的中定义主键。

尽管您已尝试这样做:

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

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

您需要 Entity Framework 才能设置ID的值。这意味着该属性需要有一个 setter。

关于c# - 错误: the entity type requires a primary key,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43503424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com