私はまだEntityFramework(現在v4.1を使用して開発中)にかなり慣れていないので、これを完全に間違った方法で行っている可能性があるので、ガイダンスを歓迎します。
現在、2つのクラスがあります。いくつかの単純なフィールドを持つItemと、アイテムとユーザーへの参照を保持するFavouriteItemです(ただし、ユーザーの関係はディスカッションとは関係ありません)。アイテムにはnull許容のDateVisibleフィールドがあり、アイテムを表示するかどうかを示すフラグとして使用しています。
表示されているアイテムのリストを取得するために、簡単なクエリを使用しています。
var items = itemRepository
.QueryAll()
.Where(i => i.DateVisible <= DateTime.Now)
明らかにQueryAllがIQueryableを返す場合。条件がもう少し複雑なので、これは簡単な例ですが、私の問題を示しています。
次に、表示されているアイテムのお気に入りのリストを返したい場合は、同様のクエリを実行できます。
var favourites= favouriteRepository
.QueryAll()
.Where(f => f.Item.DateVisible <= DateTime.Now)
これは正常に機能します。ただし、コードは重複しています。だから私がやりたいのは、どういうわけかこのコードをより中心的なものにすることです-再びItemプロパティを持つFollowingItemクラスを追加しようとしているので、コードをもう一度繰り返す必要があります-良くありません。
アイテムのリストの式を作成し始めました。これはうまく機能します。
public static Expression<Func<Item, bool>> IsVisibleExpression<Item>()
{
return item => item.DateVisible != null &&
item.DateVisible <= DateTime.Now;
}
public static IQueryable<Item> WhereVisible<Item>(this IQueryable<Item> queryable)
{
return queryable.Where(Item.IsVisibleExpression());
}
var items = itemRepository
.QueryAll()
.WhereVisible()
また、クラスごとに次の式を作成できます。
public static Expression<Func<FavouriteItem, bool>> IsVisibleExpression<FavouriteItem>()
{
return favourite => favourite.Item.DateVisible != null &&
favourite.Item.DateVisible <= DateTime.Now;
}
しかし、これもコードを複製するだけです。それらの間で同じコードを使用する方法はありますか?私はに参加できることを知っていますが、itemRepository.QueryAll().WhereVisible()
これをどこでも行うことを伴わない方法はありませんか?
更新:クラスのインターフェースを作成してみました:
public interface IEntityWithItem
{
Item Item { get; set; }
}
そして、そのための式を作成します。
public static IQueryable<TEntity> WhereItemVisible<TEntity>(this IQueryable<TEntity> queryable) where TEntity : IEntityWithItem
{
return queryable.Where(ui => ui.Item.DateVisibleFrom != null &&
ui.Item.DateVisibleFrom.Value <= DateTime.Now);
}
私が呼んだもの:
// Get the favourites
var favourites = favouriteItemRepository.QueryAll()
.WhereItemVisible()
.Where(favourite => favourite.UserId == user.Id);
ただし、 「タイプ'FavouriteItem'をタイプ'IEntityWithItem'にキャストできません。LINQtoEntitiesは、エンティティデータモデルプリミティブタイプのキャストのみをサポートしています。 」というエラーが発生します。