错误:实体类型需要主键

use*_*746 47 c# wpf entity-framework-core

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

将列表框绑定到observablecollection

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

Message =实体类型'Fruit'需要定义主键.

整个例外情况如下

System.InvalidOperationException未处理
HResult = -2146233079
Message =实体类型'Fruit'需要定义主键.
源= Microsoft.EntityFrameworkCore
堆栈跟踪:
在Microsoft.EntityFrameworkCore.Internal.ModelValidator.ShowError(字符串消息)
在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,IModelValidator验证器)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<> c__DisplayClass14_0.b__0(Object k)
at System.Collections.Concurrent.ConcurrentDictionary 2.GetOrAdd(TKey key, Func2 valueFactory)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context,IConventionSetBuilder conventionSetBuilder,IModelValidator validator)
at at 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.<AddEntityFramework>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调用点,TArgument参数)
在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(scopedCallSite scopedCallSite,供应商的ServiceProvider)
在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调用点,TArgument参数)
在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite,的ServiceProvider提供商)
在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.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](IInfrastructure
1存取器)
在Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.get_StateManager()
在Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges()
在Microsoft.EntityFrameworkCore.DbContext.TryDetectChanges()
在Microsoft.EntityFrameworkCore.DbContext.SaveChanges(布尔acceptAllChangesOnSuccess)

Fruit.MainWindow.SaveFruitCommandBinding_Executed(Object sender,ExecutedRoutedEventArgs e)中的Microsoft.EntityFrameworkCore.DbContext.SaveChanges()位于D:\ Frank\Test\Fruits\Fruits\MainWindow.xaml.cs:
System.Windows.Input中的第50行.
System.Windows.Input.CommandManager.FindCommandBinding的System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender,ExecutedRoutedEventArgs e,CommandBinding commandBinding)
中的CommandBinding.OnExecuted(Object sender,ExecutedRoutedEventArgs e)(CommandBindingCollection commandBindings,Object sender,RoutedEventArgs e, ICommand的命令,执行布尔)
在System.Windows.Input.CommandManager.FindCommandBinding(对象发件人,RoutedEventArgs E,ICommand的命令,执行布尔)
在System.Windows.Uindlement.OnExecutedThunk(Object sender,ExecutedRoutedEventArgs e)的System.Windows.Input.CommandManager.OnExecuted(Object sender,ExecutedRoutedEventArgs e)处于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,布尔值为受信任)的Windows.UIElement.RaiseEventImpl(DependencyObject sender,RoutedEventArgs args).MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource)上的System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter,IInputElement target,Boolean userInitiated)中的Windows.Input.RoutedCommand.ExecuteImpl(Object parameter,IInputElement target,Boolean userInitiated) System.Windows上的System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)中的System.Windows.Conuts.Button.OnClick()上的System.Windows.Controls.Primitives.ButtonBase.OnClick()处理,布局userInitiated) System.Windows上的System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler,Object genericTarget)中的.UIElement.OnMouseLeftButtonUpThunk(Object sender,MouseButtonEventArgs e).System.Windows.UIElement的System.Windows.EventRoute.InvokeHandlersImpl(Object source,RoutedEventArgs args,Boolean reRaised)中的System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target,RoutedEventArgs routedEventArgs)中的RoutedEventArgs.InvokeHandler(委托处理程序,Object目标).在System.Windows.RindtedEventArgs的System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler,Object genericTarget)的System.Windows.UIElement.OnMouseUpThunk(Object sender,MouseButtonEventArgs e)中的ReRaiseEventAs(DependencyObject sender,RoutedEventArgs args,RoutedEvent newEvent). System.Windows.RoutedEventHandlerInfo.InvokeHandler中的InvokeHandler(委托处理程序,Object目标)(对象目标,RoutedEventArgs routedEventArgs)System.Windows.EventRoute.InvokeHandlersImpl(Object source,RoutedEventArgs args,Boolean reRaised)在System.Windows.UIElement.RaiseEventImpl(DependencyObject sender,RoutedEventArgs args)处的System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)处于System .Windows.UIElement.RaiseEvent(RoutedEventArgs args,布尔值为受信任),System.Windows.InputManager.ProcessStagingArea(),位于System.Windows.Input.InputManager.ProcessInput(InputEventArgs输入),位于System.Windows.Input.InputProviderSite.ReportInput( System.Windows.Interop.HwndMouseInputProvider.ReportInput中的InputReport inputReport)(IntPtr hwnd,InputMode模式,Int32时间戳,RawMouseActions操作,Int32 x,Int32 y,在System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr)的System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd,WindowMessage msg,IntPtr wParam,IntPtr lParam,Boolean&handling)处的Int32轮) lParam,Boolean&handling)在MS.Win32.HwndWrapper.WndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam,Boolean&handling)处于System.Windows.Threading.ExceptionWrapper的MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o). System.Windows.Threading.Dispatcher上的System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source,Delegate callback,Object args,Int32 numArgs,Delegate catchHandler)中的InternalRealCall(委托回调,Object args,Int32 numArgs).位于MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG&msg)的MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd,Int32 msg,IntPtr wParam,IntPtr lParam)的LegacyInvokeImpl(DispatcherPriority priority,TimeSpan timeout,Delegate方法,Object args,Int32 numArgs) System.Windows.Application.RunInternal(Window)上的System.Windows.Application.RunDispatcher(Object ignore)处的System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame框架)上的System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame框架)在System.Windows.Application.Run(Window窗口)的System.Windows.Application.Run()处于Systems.AppDomain._nExecuteAssembly的Fruits.App.Main()(RuntimeAssembly程序集,System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args)的System.ThreadingAs.Tosread.ThreadProc.RunUsersAssembly()处于系统的System.Threading.ThreadHelper.ThreadStart_Context(Object state)处的String [] args). System.Threading.ExecutionContext.Run(ExecutionContext executionContext)中的System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,Object状态,Boolean preserveSyncCtx)中的Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback回调,Object状态,Boolean preserveSyncCtx) System.Threading.ThreadHelper.ThreadStart()InnerException:,ContextCallback回调,对象状态)System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback)中的System.Threading.ThreadHelper.ThreadStart_Context(Object state)上的Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()中的ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args)系统中System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)的System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,Object状态,Boolean preserveSyncCtx)中的callback,Object state,Boolean preserveSyncCtx). Threading.ThreadHelper.ThreadStart()InnerException:System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback)中的System.Threading.ThreadHelper.ThreadStart_Context(Object state)上的Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()中的ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args)系统中System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)的System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,Object状态,Boolean preserveSyncCtx)中的callback,Object state,Boolean preserveSyncCtx). Threading.ThreadHelper.ThreadStart()InnerException:System.Threading.ExecutionContext.Run上System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)的System.Threading.ThreadPel.ThreadStart_Context(Object state)中的VisualStudio.HostingProcess.HostProc.RunUsersAssembly() (ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state)at System.Threading.ThreadHelper.ThreadStart()InnerException:System.Threading.ExecutionContext.Run上System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)的System.Threading.ThreadPel.ThreadStart_Context(Object state)中的VisualStudio.HostingProcess.HostProc.RunUsersAssembly() (ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state)at System.Threading.ThreadHelper.ThreadStart()InnerException:System.Threading.ExecutionContext.Run中的RunInternal(ExecutionContext executionContext,ContextCallback回调,Object状态,Boolean preserveSyncCtx)System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,Object状态,Boolean preserveSyncCtx)(ExecutionContext executionContext,ContextCallback回调, System.Threading.ThreadHelper.ThreadStart()中的对象状态:InnerException:System.Threading.ExecutionContext.Run中的RunInternal(ExecutionContext executionContext,ContextCallback回调,Object状态,Boolean preserveSyncCtx)System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,Object状态,Boolean preserveSyncCtx)(ExecutionContext executionContext,ContextCallback回调, System.Threading.ThreadHelper.ThreadStart()中的对象状态:InnerException:System.Threading.ThreadHelper.ThreadStart()中的对象状态:InnerException: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
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

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

小智 84

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

虽然你试图这样做:

private Guid _id;
[Key]
public Guid ID
{
    get { return _id; }
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • @user1205746 `DbSet&lt;Fruit&gt;.Local` 应该是一个可以绑定的 `ObservableCollection&lt;Fruit&gt;` 。它跟踪加载到上下文中的所有实体。然后(或之前),只需确保将实体加载到上下文中(`context.Fruits.Load();`),它就应该可以工作。这要求您保持上下文至少与视图模型一样长。关于上下文应该是短期的还是长期的,意见不一。就我个人而言,在这种情况下,我会选择长期存在的上下文。 (2认同)

Ada*_*Cox 16

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

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

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

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

        // ...
Run Code Online (Sandbox Code Playgroud)

应该是这个..

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

        // ...
Run Code Online (Sandbox Code Playgroud)


A-S*_*ani 12

确保您具备以下条件:

  1. [key]如果您的主键名称不是Id或,请使用ID
  2. 使用public关键字。
  3. 主键应该有 getter 和 setter。

例子:

public class MyEntity {
   [key]
   public Guid Id {get; set;}
}
Run Code Online (Sandbox Code Playgroud)


小智 9

这对我有用:

using System.ComponentModel.DataAnnotations;

[Key]
public int ID { get; set; }
Run Code Online (Sandbox Code Playgroud)


Fre*_*red 7

您的 Id 属性需要有一个设置器。然而,设置器可以是私有的。如果属性名为“Id”,则该[Key]属性不是必需的,因为它将通过命名约定查找名称为“Id”的键。

public Guid Id { get; }              // Will not work
public Guid Id { get; set; }         // Will work
public Guid Id { get; private set; } // Will also work
Run Code Online (Sandbox Code Playgroud)


Ogg*_*las 7

如果出现错误:

实体类型“DeviceFlowCodes”需要定义主键。如果您打算使用无键实体类型,请在“OnModelCreating”中调用“HasNoKey”。有关无密钥实体类型的详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2141943

您可能正在使用具有个人用户帐户的解决方案,并且已经protected override void OnModelCreating(ModelBuilder modelBuilder)ApplicationDbContext.

该错误来自于ApiAuthorizationDbContext有一个public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }.

base.OnModelCreating(modelBuilder);通过调用解决该错误protected override void OnModelCreating

来源:

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


Dev*_*per 5

我发现错误的原因有点不同。似乎 SQLite 想要使用正确的主键类属性名称。所以...

错误的PK名称

public class Client
{
  public int SomeFieldName { get; set; }  // It is the ID
  ...
}
Run Code Online (Sandbox Code Playgroud)

正确的PK名称

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

public class Client
{
  public int ClientId { get; set; }  // It is the ID
  ...
}
Run Code Online (Sandbox Code Playgroud)

仍然可能使用错误的 PK 名称,但我们必须使用 [Key] 属性,例如

public class Client
{
   [Key]
   public int SomeFieldName { get; set; }  // It is the ID
   ...
}
Run Code Online (Sandbox Code Playgroud)