次のクエリがあります。
// Type T is constrained to a class that contains "ID" property
// propertiesToQuery is a list constructed based on type T
var set = AppContext.Set<T>();
var result = set.SelectMany(x => propertiesToQuery.Select(p => new { x.ID, Value = x.GetType().GetProperty(p.Name).GetValue(x) })
.Where(p => p.Value != null)
.Select(p => new SearchIndexItem
{
Key = p.Value.ToString(),
Url = Url.Action("Edit", type.Name, new { p.ID }),
Type = type
}));
エンティティへの linq ではクエリで PropertyInfo を使用できないため、最初にデータベースでクエリを実行し、次に目的の SelectMany() を実行するために、セットで ToList() を実行する必要があります。
これは、データベースから必要以上にクエリを実行します。これは、大量のデータがある場合に問題になります (クエリされた列は文字列型であり、他の列は BLOB である可能性があり、これらはデータを取得したくない列です)。
問題は、実行時に作成されたリストに基づいて、db からクエリされる列をどのように制限できるかということです。
式ツリーを作成してセットの Select() メソッドに渡そうとしましたが、問題は匿名型の作成にあり、型 T によって異なる場合があります。