1

MVVM を使用しているため、ビュー モデルで ObservableCollections をかなり使用しています。タイピングを節約するために、新しい ObservableCollection を作成する代わりに、IEnumerable を ObservableCollection に直接変換する拡張メソッドを使用すると便利であると判断しました。毎回。

したがって、入力する代わりに...

ObservableCollection fred = new ObservableCollection(myCollection);

...入力できます...

ObservableCollection fred = myCollection.ToObservableCollection();

明らかに、上記の人為的な例では、これによるメリットはほとんどありませんが、より大きな Linq クエリでは、これによりコードがかなりクリーンアップされる可能性があります。

とにかく、私はこのような簡単な拡張メソッドを書きました...

public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> collection) {
  if (collection != null) {
    return new ObservableCollection<T>(collection);
  }
  throw new ArgumentNullException("collection");
}

ただし、これを使用しようとすると、例外が発生します...

LINQ to Entities は、'System.Collections.ObjectModel.ObservableCollection`1[VisionRT.CRM.Entities.SiteOverview] ToObservableCollection[SiteOverview](System.Collections.Generic.IEnumerable`1[VisionRT.CRM.Entities.SiteOverview] メソッドを認識しません。 )' メソッドであり、このメソッドは store 式に変換できません。

ToList() 拡張メソッドがまったく同じことを行いますが、機能するという事実がなければ、これは理解できます。

私の方法が失敗する理由と、それを修正する方法はありますか? ありがとう。

4

2 に答える 2

0

問題は、enrity フレームワークに対してクエリを実行していることだと思います。クエリは実際には SQL サーバーで実行されます。そこには(リストとは対照的に)拡張メソッドのサポートがないため、失敗します。

于 2013-02-28T19:21:46.190 に答える
0

私は過去に同様の問題を抱えていました (特に LINQ-to-Entities で)。一般的な解決策は、式ツリーを使用して、実行時に LINQ を延期するのではなく、コンパイル時に LINQ を構築することです。

これを試しましたか:

public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> collection)
{
    var observableCollection = new ObservableCollection<T>();

    foreach (var item in collection)
    {
        observableCollection.Add(item);
    }

    return observableCollection;
}

それが違いを生むかどうかはわかりませんが、試してみる価値はあります。

オマー・シュライファーの答えについて:

Entity Framework で拡張メソッドを許可する例は、そのdbContext.Set<T>モニカを一般化しようとすることです。これを行う代わりに:

dbContext.People.Where(p => p.Id == 1234);

私はこれができるようにしたかった:

dbContext.Get<Person>(p => p.Id == 1234);

この方法は機能しません:

public static T Get<T>(this DapperDbContext dbContext, int id, string property = "Id") where T : class
{
    return dbContext.Set<T>().FirstOrDefault(t => (int)t.GetType().GetProperty(property).GetValue(t) == id);
}

ただし、これは機能します。

public static T Get<T>(this DapperDbContext dbContext, int id, string property = "Id") where T : class
{
    var parameter = Expression.Parameter(typeof(T));
    var lambda = Expression.Lambda<Func<T, bool>>(Expression.Equal(Expression.Property(parameter, property)
        , Expression.Constant(id)), parameter);
    return dbContext.Set<T>().FirstOrDefault(lambda);
}

シナリオで同様のことができる場合があります。

お役に立てれば。

于 2013-03-08T12:23:21.370 に答える