Ich möchte die in diesem Thread gestellte Frage erweitern
Listenfeld an beobachtbare Sammlung binden
indem Sie ihm die Möglichkeit geben, die Daten dauerhaft zu speichern. Die Struktur ist größtenteils dieselbe, außer dass ich Entity Framework Core installiert und eine DbContext
Klasse für die Datensätze erstellt habe. Ich habe eine Schaltfläche hinzugefügt, um das Dataset in SQL Server zu speichern. Der Kompilierungsfehler ist nicht aufgetreten, aber als ich versuchte, die Daten in der Datenbank zu speichern, wurde folgende Laufzeitausnahme angezeigt:
Nachricht = Für den Entitätstyp 'Frucht' muss ein Primärschlüssel definiert werden.
Die gesamte Ausnahme in ihrer Gesamtheit ist unten aufgeführt
System.InvalidOperationException wurde nicht behandelt
HResult = -2146233079
Message = Für den Entitätstyp 'Fruit' muss ein Primärschlüssel definiert werden.
Source = Microsoft.EntityFrameworkCore
Stacktrace:
bei Microsoft.EntityFrameworkCore.Internal.ModelValidator.ShowError (String message)
an Microsoft.EntityFrameworkCore.Internal.ModelValidator.EnsureNonNullPrimaryKeys (IModel Modell)
bei Microsoft.EntityFrameworkCore.Internal.ModelValidator.Validate (IModel Modell)
bei Microsoft.EntityFrameworkCore.Internal.RelationalModelValidator.Validate (IModel-Modell)
bei Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel (DbContext-Kontext, IConventionSetBuilder-KonventionSetBuilder, IModelValidator-Validator)
bei Microsoft.EntityFrameworkCore.Infrastructure.ModelSource. <> c__DisplayClass14_0.b__0 (Object k)
bei System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func
2 valueFactory)
bei Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel (DbContext Zusammenhang IConventionSetBuilder conventionSetBuilder, IModelValidator Validator)
bei Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel ()
bei Microsoft.EntityFrameworkCore.Internal.LazyRef 2.VisitCallSite (IServiceCallSite callSite, TArgument-Argument) bei Microsoft.Extensions.DependencyInjection.ServiceLit1.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
bei Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.VisitCallSite (IServiceCallSite callSite, TArgument Argument) bei Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped (ScopedCallSite scopedCallSite, Serviceprovider - Provider ) bei Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 1 Accessor) bei Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.get_StateManager () bei Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges () bei Microsoft.EntityFrameworkCore.DbContext.TryDetectChanges ()2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.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
bei Microsoft.EntityFrameworkCore.DbContext.SaveChanges (Boolean acceptAllChangesOnSuccess)
bei Microsoft.EntityFrameworkCore.DbContext.SaveChanges ()
bei Fruits.MainWindow.SaveFruitCommandBinding_Executed (Objektabsender, ExecutedRoutedEventArgs e) in D: \ Frank \ Test \ Fruits \ Fruits \ MainWindow.xaml.cs: Zeile 50
bei SystemW. CommandBinding.OnExecuted (Objektabsender, ExecutedRoutedEventArgs e)
unter System.Windows.Input.CommandManager.ExecuteCommandBinding (Objektabsender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
unter System.Windows.Input.CommandManager.FindCommandBind, ICommand-Befehl, Boolean execute)
bei System.Windows.Input.CommandManager.FindCommandBinding (Objektabsender, RoutedEventArgs e, ICommand-Befehl, Boolean execute)
at System.Windows.Input.CommandManager.OnExecuted (Objektabsender, ExecutedRoutedEventArgs e) at System.Windows.UIElement.OnExecutedThunk (Objektabsender, ExecutedRoutedEventArgs e) at System.Windows.Input.ExecutedRoutedEventArgs.Inv System.Windows.RoutedEventArgs.InvokeHandler (Delegate-Handler, Objektziel) bei System.Windows.RoutedEventHandlerInfo.InvokeHandler (Objektziel, RoutedEventArgs routedEventArgs) bei System.Windows.EventRoute.InvokeHandlersImpl (Objektquelle) Windows.UIElement.RaiseEventImpl (DependencyObject-Absender, RoutedEventArgs-Argumente) bei System.Windows.UIElement.RaiseEvent (RoutedEventArgs-Argumente, Boolean Trusted) bei System.Windows.Input.RoutedCommand.ExecuteImpl (Objektparameter, IInputElement-Ziel, Boolean userInitiated) bei System.Windows.Input.RoutedCommand.ExecuteCore (Objektparameter, IInputElement-Ziel, Boolean userInitiated) bei MS.Internal.Commands.CommandHelecoreCommand , Boolean userInitiated) bei System.Windows.Controls.Primitives.ButtonBase.OnClick () bei System.Windows.Controls.Button.OnClick () bei System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp .UIElement.OnMouseLeftButtonUpThunk (Objektabsender, MouseButtonEventArgs e) bei System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler (Delegate genericHandler, Object genericTarget) bei System.Windows.RoutedEventArgs.InvokeHandler (Delegate-Handler, Objektziel) bei System.Windows.RoutedEventHandlerInfo.InvokeHandler (Objektziel, RoutedEventArgs routedEventArgs) bei System.Windows.EventRoute.InvokeHandlersImpl (Objektquelle, RoutedEventUgs. ReRaiseEventAs (DependencyObject-Absender, RoutedEventArgs-Argumente, RoutedEvent newEvent) bei System.Windows.UIElement.OnMouseUpThunk (Objektabsender, MouseButtonEventArgs e) bei System.Windows.Input.MouseButtonEventArgs.InvokeEventHindHand. InvokeHandler (Delegate-Handler, Objektziel) bei System.Windows.RoutedEventHandlerInfo.InvokeHandler (Objektziel,RoutedEventArgs routedEventArgs) bei System.Windows.EventRoute.InvokeHandlersImpl (Objektquelle, RoutedEventArgs-Argumente, Boolean reRaised) bei System.Windows.UIElement.RaiseEventImpl (DependencyObject-Absender, RoutedEventArgs-Argumente) .Windows.UIElement.RaiseEvent (RoutedEventArgs-Argumente, Boolean Trusted) bei System.Windows.Input.InputManager.ProcessStagingArea () bei System.Windows.Input.InputManager.ProcessInput (InputEventArgs-Eingabe) bei System.Windows.Input.InputPin InputReport inputReport) bei System.Windows.Interop.HwndMouseInputProvider.ReportInput (IntPtr hwnd, InputMode-Modus, Int32-Zeitstempel, RawMouseActions-Aktionen, Int32 x, Int32 y,Int32-Rad) bei System.Windows.Interop.HwndMouseInputProvider.FilterMessage (IntPtr hwnd, WindowMessage-Nachricht, IntPtr wParam, IntPtr lParam, Boolean & behandelt) bei System.Windows.Interop.HwndSource.InputFilPrtrPP lParam, Boolean & behandelt) bei MS.Win32.HwndWrapper.WndProc (IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean & behandelt) bei MS.Win32.HwndSubclass.DispatcherCallbackOperation (Object o )Thr.Wind. InternalRealCall (Rückruf delegieren, Objektargumente, Int32 numArgs) bei System.Windows.Threading.ExceptionWrapper.TryCatchWhen (Objektquelle, Rückruf delegieren, Objektargumente, Int32 numArgs, CatchHandler delegieren) bei System.Windows.Threading.Dispatcher.LegacyInvokeImpl (DispatcherPriority-Priorität, TimeSpan-Zeitlimit, Delegate-Methode, Objektargumente, Int32-Nummern) bei MS.Win32.HwndSubclass.SubclassWndProc (IntPtr hwnd, Int32-Nachricht, IntPtr wParam, IntPtr lParam) bei MS.WinMU. bei System.Windows.Threading.Dispatcher.PushFrameImpl (DispatcherFrame-Frame) bei System.Windows.Threading.Dispatcher.PushFrame (DispatcherFrame-Frame) bei System.Windows.Application.RunDispatcher (Objekt ignorieren) bei System.Windows.Application.RunInternal Fenster) bei System.Windows.Application.Run (Fensterfenster) bei System.Windows.Application.Run () bei Fruits.App.Main () bei System.AppDomain._nExecuteAssembly (RuntimeAssembly-Assembly,String [] Argumente) bei System.AppDomain.ExecuteAssembly (Zeichenfolge AssemblyFile, Evidence AssemblySecurity, String [] Argumente) bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly () bei System.Threading.ThreadHelper.ThreadStart_Context (Objektstatus) System. Threading.ExecutionContext.RunInternal (ExecutionContext ExecutionContext, ContextCallback-Rückruf, Objektstatus, Boolean PreserveSyncCtx) bei System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, ContextCallback Callback, Objektstatus, Boolean PreserveSyncConxCon , ContextCallback-Rückruf, Objektstatus) bei System.Threading.ThreadHelper.ThreadStart () InnerException:ExecuteAssembly (String AssemblyFile, Evidence AssemblySecurity, String [] Argumente) bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly () bei System.Threading.ThreadHelper.ThreadStart_Context (Objektstatus) bei System.Threading.ExecutionContextContextContextContextContextContextContextContext Rückruf, Objektstatus, BooleanerveSyncCtx) bei System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, ContextCallback-Rückruf, Objektstatus, Boolean PreserveSyncCtx) bei System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, ContextCbacktext) Threading.ThreadHelper.ThreadStart () InnerException:ExecuteAssembly (String AssemblyFile, Evidence AssemblySecurity, String [] args) bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly () bei System.Threading.ThreadHelper.ThreadStart_Context (Objektstatus) bei System.Threading.ExecutionContextContextContextContextContextContextContext Rückruf, Objektstatus, BooleanerveSyncCtx) bei System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, ContextCallback-Rückruf, Objektstatus, Boolean PreserveSyncCtx) bei System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, ContextCbacktext) Threading.ThreadHelper.ThreadStart () InnerException:VisualStudio.HostingProcess.HostProc.RunUsersAssembly () bei System.Threading.ThreadHelper.ThreadStart_Context (Objektstatus) bei System.Threading.ExecutionContext.RunInternal (ExecutionContext ExecutionContext, ContextCallback-Rückruf, ObjectContext, ContextCallback-Rückruf (ExecutionContext executeContext, ContextCallback-Rückruf, Objektstatus, BooleanerveSyncCtx) bei System.Threading.ExecutionContext.Run (ExecutionContext-Ausführungskontext, ContextCallback-Rückruf, Objektstatus) bei System.Threading.ThreadHelper.ThreadStart () InnerException:VisualStudio.HostingProcess.HostProc.RunUsersAssembly () bei System.Threading.ThreadHelper.ThreadStart_Context (Objektstatus) bei System.Threading.ExecutionContext.RunInternal (ExecutionContext ExecutionContext, ContextCallback-Rückruf, ObjectContext, ContextCallback-Rückruf (ExecutionContext executeContext, ContextCallback-Rückruf, Objektstatus, BooleanerveSyncCtx) bei System.Threading.ExecutionContext.Run (ExecutionContext-Ausführungskontext, ContextCallback-Rückruf, Objektstatus) bei System.Threading.ThreadHelper.ThreadStart () InnerException:RunInternal (ExecutionContext Ausführungskontext, ContextCallback-Rückruf, Objektstatus, BooleanerveSyncCtx) bei System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, ContextCallback-Rückruf, Objektstatus, Boolean PreserveSyncCtx) bei System.Threading.ContextConx Objektstatus) bei System.Threading.ThreadHelper.ThreadStart () InnerException:RunInternal (ExecutionContext Ausführungskontext, ContextCallback-Rückruf, Objektstatus, BooleanerveSyncCtx) bei System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, ContextCallback-Rückruf, Objektstatus, Boolean PreserveSyncCtx) bei System.Threading.ContextConx Objektstatus) bei System.Threading.ThreadHelper.ThreadStart () InnerException:Objektstatus) bei System.Threading.ThreadHelper.ThreadStart () InnerException:Objektstatus) bei System.Threading.ThreadHelper.ThreadStart () InnerException:
Dies ist die aktualisierte Klasse Obst:
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
}
}
Das aktualisierte MainWindows xaml (um eine Schaltfläche zum Speichern hinzuzufügen)
<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>
und mein Code hinter den Hauptfenstern (Handler hinzugefügt)
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;
}
}
}
Mein neu hinzugefügter 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");
}
}
}
Andere Klassen bleiben unverändert, aber ich habe sie trotzdem aufgelistet:
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>
Die Struktur meines Projekts
Meine Tabelle 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]
Bitte geben Sie an, warum in der Nachricht angegeben wurde, dass kein Primärschlüssel vorhanden war, solange dieser vorhanden ist
quelle
Antworten:
Diese Ausnahmemeldung bedeutet nicht, dass ein Primärschlüssel in Ihrer Datenbank definiert werden muss , sondern dass ein Primärschlüssel in Ihrer Klasse definiert werden muss .
Obwohl Sie dies versucht haben:
Dies hat keine Auswirkung, da Entity Framework schreibgeschützte Eigenschaften ignoriert. Es muss: Wenn es einen
Fruits
Datensatz aus der Datenbank abruft , erstellt es einFruit
Objekt und ruft dann die Eigenschaftssetter für jede zugeordnete Eigenschaft auf. Das wird für schreibgeschützte Eigenschaften niemals funktionieren.Sie benötigen Entity Framework, um den Wert von festlegen zu können
ID
. Dies bedeutet, dass die Eigenschaft einen Setter haben muss.quelle
DbSet<Fruit>.Local
sollte eine sein, an dieObservableCollection<Fruit>
Sie binden können. Es verfolgt alle in den Kontext geladenen Entitäten. Stellen Sie dann (oder vorher) einfach sicher, dass Sie die Entitäten in den Kontext laden (context.Fruits.Load();
) und es sollte funktionieren. Dies erfordert, dass Sie den Kontext mindestens so lange wie Ihr Ansichtsmodell beibehalten. Die Meinungen darüber, ob Kontexte kurzlebig oder langlebig sein sollten, gehen auseinander. Persönlich würde ich mich in diesem Fall für einen langlebigen Kontext entscheiden.ObservableCollection<Fruit>
, nicht wahr? Sie tun dies in dem Code, den Sie in Ihrer Frage gezeigt haben. Alles, was Sie tun müssen, anstatt ein brandneuesObservableCollection<Fruit>
Objekt zu erstellen, ist das, das EF für Sie erstellt.Ich bin mit einem ähnlichen Fehler hierher gekommen:
Nachdem ich die Antwort von hvd gelesen hatte, wurde mir klar, dass ich einfach vergessen hatte, mein Schlüsselobjekt "öffentlich" zu machen. Diese..
namespace MyApp.Models.Schedule { public class MyType { [Key] int Id { get; set; } // ...
Sollte das sein ..
namespace MyApp.Models.Schedule { public class MyType { [Key] public int Id { get; set; } // must be public! // ...
quelle
Ich habe eine etwas andere Fehlerursache gefunden. Anscheinend möchte SQLite den korrekten Eigenschaftsnamen der Primärschlüsselklasse verwenden. Damit...
Falscher PK-Name
public class Client { public int SomeFieldName { get; set; } // It is the ID ... }
Richtiger PK-Name
public class Client { public int Id { get; set; } // It is the ID ... } public class Client { public int ClientId { get; set; } // It is the ID ... }
Es ist immer noch möglich, einen falschen PK-Namen zu verwenden, aber wir müssen das [Key] -Attribut wie verwenden
public class Client { [Key] public int SomeFieldName { get; set; } // It is the ID ... }
quelle
Ihre ID-Eigenschaft muss einen Setter haben. Der Setter kann jedoch privat sein. Das
[Key]
Attribut ist nicht erforderlich, wenn die Eigenschaft "Id" heißt, da sie über die Namenskonvention gefunden wird, bei der nach einem Schlüssel mit dem Namen "Id" gesucht wird.public Guid Id { get; } // Will not work public Guid Id { get; set; } // Will work public Guid Id { get; private set; } // Will also work
quelle
In meinem Fall stellte ich fest, dass das Problem darin bestand, dass ich Eigenschaften wie diese verwendete:
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
Ich bin mir nicht sicher, ob es einen besseren Weg gibt, es zu lösen, aber ich habe das Attribut Email und PhoneNumber in eine Zeichenfolge geändert. Problem gelöst.
quelle
Das hat bei mir funktioniert:
using System.ComponentModel.DataAnnotations; [Key] public int ID { get; set; }
quelle
Keine der Antworten funktionierte, bis ich die HasNoKey () -Methode aus der Entität entfernt habe. Vergessen Sie nicht, dies aus Ihrem Datenkontext zu entfernen, da sonst das Attribut [Schlüssel] nichts behebt.
quelle
Stellen Sie sicher, dass Sie die folgende Bedingung haben:
[key]
Sie diese Option, wenn Ihr Primärschlüsselname nichtId
oder lautetID
.public
Schlüsselwort.Beispiel:
public class MyEntity { [key] public Guid Id {get; set;} }
quelle
Mit Scaffold-DbContext entfernt und wieder in die Tabelle eingefügt, und der Fehler wurde behoben
quelle
Als ich den Befehl Scaffold-DbContext verwendete, enthielt er weder die Annotation "[key]" in den Modelldateien noch den Eintrag "entity.HasKey (..)" in den Blöcken "modelBuilder.Entity". Meine Lösung bestand darin, in jedem "modelBuilder.Entity" -Block in der Datei * Context.cs eine Zeile wie diese einzufügen:
Ich sage nicht, dass dies besser oder sogar der richtige Weg ist. Ich sage nur, dass es bei mir funktioniert hat.
quelle
Ein weiterer Grund kann sein, dass Ihre Entitätsklasse mehrere Eigenschaften hat, die irgendwie benannt sind. Wenn Sie
/.*id/i
also mit der ID-Groß- / Kleinschreibung ohne Berücksichtigung und ohne Elementartyp enden, gibt es kein[Key]
Attribut.EF wird nämlich versuchen, die PK selbst herauszufinden, indem nach elementaren typisierten Eigenschaften gesucht wird, die mit ID enden .
Siehe meinen Fall:
public class MyTest, IMustHaveTenant { public long Id { get; set; } public int TenantId { get; set; } [MaxLength(32)] public virtual string Signum{ get; set; } public virtual string ID { get; set; } public virtual string ID_Other { get; set; } }
Fragen Sie nicht - Lecacy-Code. Das
Id
wurde sogar geerbt, so dass ich es nicht verwenden konnte[Key]
(nur den Code hier vereinfachen)Aber hier ist EF total verwirrt.
Was geholfen hat, war die Verwendung von modelbuilder in der DBContext-Klasse.
modelBuilder.Entity<MyTest>(f => { f.HasKey(e => e.Id); f.HasIndex(e => new { e.TenantId }); f.HasIndex(e => new { e.TenantId, e.ID_Other }); });
Der Index für PK ist implizit.
quelle