I’ve managed to stump myself with LINQ. I am trying to create an editable datagrid in a WPF app using a subset gathered from a LINQ query:
var LookUpEvents = from d in ThisData.Events.Local
where d.StartDate.Value.Date <= DateTime.Now.Date &&
(d.EndDate.HasValue == false || d.EndDate.Value.Date >= DateTime.Now.Date)
select d;
RangeEventGrid.ItemsSource = LookUpEvents;
RangeEventGrid.Items.Refresh();
This query works, and the datagrid is populated however I am unable to edit the datagrid, when trying to this exception is thrown:
"'EditItem' is not allowed for this view."
at System.Windows.Controls.ItemCollection.System.ComponentModel.IEditableCollectionView.EditItem(Object item)
at System.Windows.Controls.DataGrid.EditRowItem(Object rowItem)
When loading the full dataset using:
ThisData.Events.Load();
FullEventGrid.ItemsSource = ThisData.Events.Local;
Everything works fine and the data is editable. The XAML used is identical (I have also tried swapping the bound datagrids and the full result remains editable and the query throws the exception still) and the only difference between these is the query. When I try to change the query I end up with a new exception:
The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
The query used for that:
var LookUpEvents = from d in ThisData.Events
where d.StartDate.Value.Date <= DateTime.Now.Date &&
(d.EndDate.HasValue == false || d.EndDate.Value.Date >= DateTime.Now.Date)
select d;
LookUpEvents.Load(); //Exception thrown here.
RangeEventGrid.ItemsSource = LookUpEvents;
RangeEventGrid.Items.Refresh();
The really weird thing about that exception (weird to me at least) is that I use DateTime comparison in other queries that do not throw any exceptions, for example this query in another place works fine:
var LookUpSessions = from d in ThisData.Sessions
where d.EndTime.Hour >= (DateTime.Now.Hour - 1) && d.StartTime.Hour <= (DateTime.Now.Hour + 2)
&& d.Event.IsActive == true
orderby d.StartTime.Hour, d.StartTime.Minute
select d;
Is it not possible to bind a LINQ query result to a DataGrid to be editable? That seems like it’d be a huge oversight if that’s the case. I feel like it’s much more likely I’m just missing something basic since LINQ, WPF and EF are all brand new to me.
Thanks in advance.
To make editing data in the GridView possible you cannot use an
IEnumerable<T>orIQueryable<T>as the items source. You need a collection type that implemntsIListandIEnumerable<T>orIQueryable<T>don’t.A possible solution is that you create an
ObservableCollection<T>(that does implementIList) from your LINQ query:This is also the reason why
does work because
Localis already of typeObservableCollection<Event>.Your very first query doesn’t throw an exception (although you are using
DateTime.Date) because it is not a LINQ-to-Entities/database query. It is a LINQ-to-Objects query that runs in memory on theLocalcollection. There is no database query involved.If you remove
Localyou run LINQ-to-Entities and LINQ-to-Entities doesn’t support all methods and properties that LINQ-to-Objects does, especially it doesn’t supportDateTime.Date(but apparently is does supportDateTime.Hour).To perform the comparison by
Datein a LINQ-to-Entities query you can use EntityFunctions:Or maybe the
EntityFunction.DiffDaysfunction is an option as well.