Ошибка: для типа сущности требуется первичный ключ

Я хотел бы расширить вопрос, заданный в этой теме

Связывание списка с наблюдаемым коллекцией

предоставляя ему возможность постоянного хранения данных. Структура в основном такая же, за исключением того, что я установил Entity Framework Core, создал класс DbContext для хранения записей. Я добавил кнопку, чтобы сохранить набор данных на SQL Server. Я не столкнулся с компиляционной ошибкой, но когда я попытался сохранить данные в базе данных, я получил это исключение во время выполнения:

Сообщение = Тип сущности 'Fruit' требует определения первичного ключа.

Полное исключение в целом приведено ниже

Исключено событие System.InvalidOperationException

HResult = -2146233079
Message = Тип сущности 'Fruit' требует определения первичного ключа.
Источник = Microsoft.EntityFrameworkCore
StackTrace:
в Microsoft.EntityFrameworkCore.Internal.ModelValidator.ShowError(сообщение String)
в Microsoft.EntityFrameworkCore.Internal.ModelValidator.EnsureNonNullPrimaryKeys(модель-модель)
в Microsoft.EntityFrameworkCore.Internal.ModelValidator.Validate(модель-модель)
в Microsoft.EntityFrameworkCore.Internal.RelationalModelValidator.Validate(модель-образец)
в Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(контекст DbContext, соглашение IConventionSetBuilderSetBuilder, валидатор IModelValidator)
в Microsoft.EntityFrameworkCore.Infrastructure.ModelSource. < > c__DisplayClass14_0.b__0 (Object k)
в System.Collections.Concurrent.ConcurrentDictionary 2.GetOrAdd(TKey key, Func 2 valueFactory)
в Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(контекст DbContext, соглашение IConventionSetBuilderSetBuilder, валидатор IModelValidator)
в 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 callSite, аргумент 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 callSite, аргумент 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 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 (отправитель объекта, ExecutedRoutedEventArgs e) в D:\Frank\Test\Fruits\Fruits\MainWindow.xaml.cs: строка 50
в System.Windows.Input.CommandBinding.OnExecuted(отправитель объекта, ExecutedRoutedEventArgs e)
в System.Windows.Input.CommandManager.ExecuteCommandBinding(отправитель объекта, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
в System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, отправитель объекта, RoutedEventArgs e, команда ICommand, Boolean execute)
в System.Windows.Input.CommandManager.FindCommandBinding(отправитель объекта, RoutedEventArgs e, команда ICommand, Boolean execute)
в System.Windows.Input.CommandManager.OnExecuted(отправитель объекта, ExecutedRoutedEventArgs e)            в System.Windows.UIElement.OnExecutedThunk(отправитель объекта, ExecutedRoutedEventArgs e)            в System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Делегат genericHandler, Object target)            в System.Windows.RoutedEventArgs.InvokeHandler(обработчик делегата, объект-объект)            в System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)            в System.Windows.EventRoute.InvokeHandlersImpl(источник объекта, аргументы RoutedEventArgs, логические значения reRaised)            в System.Windows.UIElement.RaiseEventImpl(DependencyObject отправитель, аргументы RoutedEventArgs)            в System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)            в System.Windows.Input.RoutedCommand.ExecuteImpl(параметр объекта, цель IInputElement, логическое значение userInitiated)            в System.Windows.Input.RoutedCommand.ExecuteCore(параметр объекта, цель IInputElement, логическое значение userInitiated)            в MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated)            в System.Windows.Controls.Primitives.ButtonBase.OnClick()            в System.Windows.Controls.Button.OnClick()            в System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)            в System.Windows.UIElement.OnMouseLeftButtonUpThunk(отправитель объекта, MouseButtonEventArgs e)            в System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Делегат genericHandler, Object genericTarget)            в System.Windows.RoutedEventArgs.InvokeHandler(обработчик делегата, объект-объект)            в System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)            в System.Windows.EventRoute.InvokeHandlersImpl(источник объекта, аргументы RoutedEventArgs, логические значения reRaised)            в System.Windows.UIElement.ReRaiseEventAs(отправитель DependencyObject, аргументы RoutedEventArgs, RoutedEvent newEvent)            в System.Windows.UIElement.OnMouseUpThunk(отправитель объекта, MouseButtonEventArgs e)            в System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Делегат genericHandler, Object genericTarget)            в System.Windows.RoutedEventArgs.InvokeHandler(обработчик делегата, объект-объект)            в System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)            в System.Windows.EventRoute.InvokeHandlersImpl(источник объекта, аргументы RoutedEventArgs, логические значения reRaised)            в System.Windows.UIElement.RaiseEventImpl(DependencyObject отправитель, аргументы RoutedEventArgs)            в System.Windows.UIElement.RaiseTrustedEvent(Аргументы RoutedEventArgs)            в System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)            в System.Windows.Input.InputManager.ProcessStagingArea()            в System.Windows.Input.InputManager.ProcessInput(вход InputEventArgs)            в System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)            в System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, режим InputMode, метка времени Int32, действия RawMouseActions, Int32 x, Int32 y, колесо Int32)            в System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean & обработано)            в System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean & обработано)            на MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean & обработано)            на MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)            в System.Windows.Threading.ExceptionWrapper.InternalRealCall(обратный вызов делегата, объектные аргументы, int32 numArgs)            в System.Windows.Threading.ExceptionWrapper.TryCatchWhen(источник объекта, обратный вызов делегата, аргументы объекта, Int32 numArgs, делегат catchHandler)            в System.Windows.Threading.Dispatcher.LegacyInvokeImpl(приоритет DispatcherPriority, тайм-аут TimeSpan, метод делегирования, аргументы объектов, Int32 numArgs)            на MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)            в MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG & msg)            в System.Windows.Threading.Dispatcher.PushFrameImpl(Рамка DispatcherFrame)            в System.Windows.Threading.Dispatcher.PushFrame(Рамка DispatcherFrame)            в System.Windows.Application.RunDispatcher(Object ignore)            в System.Windows.Application.RunInternal(окно окна)            в System.Windows.Application.Run(окно окна)            в System.Windows.Application.Run()            на Fruits.App.Main()            в System.AppDomain._nExecuteAssembly (сборка RuntimeAssembly, String [] args)            в System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String [] args)            в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()            в System.Threading.ThreadHelper.ThreadStart_Context (состояние объекта)            в System.Threading.ExecutionContext.RunInternal(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта, Boolean preserveSyncCtx)            в System.Threading.ExecutionContext.Run(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта, Boolean preserveSyncCtx)            в System.Threading.ExecutionContext.Run(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта)            в 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");
        }
    }
}

Другие классы остаются неизменными, но я все равно их перечислил:

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>

Структура моего проекта

введите описание изображения здесь

Моя таблица в 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]

Пожалуйста, сообщите, почему в сообщении говорилось, что первичного ключа нет, пока он существует.

Ответ 1

Это сообщение об исключении не означает, что в вашей базе данных должен быть указан первичный ключ, это означает, что для вашего класса должен быть определен первичный ключ.

Хотя вы попытались сделать это:

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

Это не влияет, поскольку Entity Framework игнорирует свойства только для чтения. Он должен: когда он извлекает запись Fruits из базы данных, он создает объект Fruit, а затем вызывает средства определения свойств для каждого отображаемого свойства. Это никогда не будет работать для свойств только для чтения.

Вам нужна платформа Entity Framework для установки значения ID. Это означает, что свойство должно иметь сеттер.

Ответ 2

Я пришел сюда с аналогичной ошибкой:

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!

        // ...

Ответ 3

Ваше свойство Id должно иметь установщик. Однако сеттер может быть приватным. Атрибут [Key] необязателен, если свойство называется "Id", так как оно будет найдено в соглашении об именах, где оно ищет ключ с именем "Id".

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

Ответ 4

Я нашел немного другую причину ошибки. Кажется, что SQLite хочет использовать правильное имя свойства класса первичного ключа. Так...

Неверное имя ПК

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

Правильное имя ПК

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

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

Можно по-прежнему использовать неправильное имя PK, но мы должны использовать атрибут [Key], например

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

Ответ 5

Тип сущности 'DisplayFormatAttribute' требует определения первичного ключа.

В моем случае я понял, что проблема в том, что я использовал такие свойства:

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

Не уверен, что есть лучший способ решить эту проблему, но я изменил атрибут Email и PhoneNumber на строку. Задача решена.

Ответ 6

Спасибо за ответ. У меня было 2 поля с URLattribute, который вызывал эту ошибку, поэтому после перехода на строку миграция прошла.

Ответ 7

у меня была похожая ошибка, только не поставил [KEY]

[Key] int MyId {get; set; задавать; } }

Поблагодарить

Ответ 8

Ни один из ответов не работал, пока я не удалил метод HasNoKey() из сущности. Не забудьте удалить это из контекста данных, иначе атрибут [Key] ничего не исправит.