我已经成功地使用LINQ。我正在尝试使用从LINQ查询收集的子集在WPF应用程序中创建可编辑的数据网格:
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();
此查询有效,并且填充了数据网格,但是当尝试抛出此异常时,我无法编辑数据网格:
"'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)
使用以下方法加载完整数据集时
ThisData.Events.Load();
FullEventGrid.ItemsSource = ThisData.Events.Local;
一切正常,数据可编辑。使用的XAML是相同的(我也尝试交换绑定的数据网格,完整的结果仍然可编辑,查询仍抛出异常),这些之间的唯一区别是查询。当我尝试更改查询时,我最终会遇到一个新的异常:
The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
用于此的查询:
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();
关于该异常的奇怪之处(至少对我来说很奇怪)是我在其他没有抛出异常的查询中使用DateTime比较,例如在另一个地方的这个查询工作正常:
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;
是否无法将LINQ查询结果绑定到DataGrid以进行编辑?如果是这样的话,那似乎是一个巨大的疏忽。我觉得我很可能只是缺少一些基本的东西,因为LINQ,WPF和EF对我来说都是全新的。
提前致谢。
答案 0 :(得分:4)
使GridView中的编辑数据可以you cannot use an IEnumerable<T>
or IQueryable<T>
作为项目来源。您需要一个实现IList
和IEnumerable<T>
或IQueryable<T>
的集合类型。
一种可能的解决方案是从LINQ查询中创建ObservableCollection<T>
(确实实现IList
):
RangeEventGrid.ItemsSource = new ObservableCollection<Event>(LookUpEvents);
这也是
的原因FullEventGrid.ItemsSource = ThisData.Events.Local;
确实有效,因为Local
已经是ObservableCollection<Event>
类型。
您的第一个查询不会抛出异常(尽管您使用的是DateTime.Date
),因为它不是LINQ到实体/数据库查询。它是一个LINQ-to-Objects查询,在Local
集合的内存中运行。没有涉及数据库查询。
如果删除Local
,则运行LINQ-to-Entities,而LINQ-to-Entities不支持LINQ-to-Objects所做的所有方法和属性,尤其是它不支持{{1} (但显然支持DateTime.Date
)。
要在LINQ-to-Entities查询中按DateTime.Hour
执行比较,您可以使用EntityFunctions:
Date
或许var today = DateTime.Now.Date;
var LookUpEvents = from d in ThisData.Events
where EntityFunction.TruncateTime(d.StartDate) <= today &&
(!d.EndDate.HasValue ||
EntityFunction.TruncateTime(d.EndDate) >= today)
select d;
函数也是一个选项。
答案 1 :(得分:1)
问题解决了!
为绑定添加了.ToList()
,它确实有效!
完整的LINQ查询:
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;
// Old binding: RangeEventGrid.ItemsSource = LookUpEvents;
// New binding:
RangeEventGrid.ItemsSource = LookUpEvents.ToList(); // .ToList() Fixes it!
RangeEventGrid.Items.Refresh();
为荣