0

私はなんとか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はすべて私にとってまったく新しいものであるため、基本的なものが欠けている可能性がはるかに高いと感じています。

前もって感謝します。

4

2 に答える 2

4

GridViewでのデータの編集を可能にするために、またはをアイテムソースとして使用することはできません。IEnumerable<T>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-to-Entities / databaseクエリではないため、(使用している場合でも)例外をスローしません。Localこれは、コレクションのメモリで実行されるLINQ-to-Objectsクエリです。関係するデータベースクエリはありません。

削除するLocalと、LINQ-to-Entitiesを実行し、LINQ-to-EntitiesはLINQ-to-Objectsがサポートするすべてのメソッドとプロパティをサポートしません。特にサポートしませんDateTime.Date(ただし、明らかにサポートしDateTime.Hourます)。

DateLINQ-to-Entitiesクエリで比較を実行するには、 EntityFunctionsを使用できます。

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;

または、EntityFunction.DiffDays関数もオプションである可能性があります。

于 2012-11-08T22:06:10.170 に答える
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();

http://xkcd.com/979/に敬意を表して自己回答

于 2012-11-08T22:03:18.330 に答える