var query1 = dbContext.MainTable.Where(m => m.MainId == _mainId).SelectMany(sub => sub.SubTable1)
.Select(sub1 => new
{
sub1.CategoryName,
VisibleDivisions = sub1.SubTable2
.Where(sub2 => sub2.Status == "Visible")
.Select(sub2 => new
{
/* select only what needed */
})
});
私のメインテーブルから始めて、私はすべてSUB1のすべてと一緒に選択取得したいですサブ2はサブ1に関連しています。 クエリは期待通りに機能し、データベースにヒットする単一のクエリを生成します。
私の質問は内部Where
の部分についてです。このフィルタはアプリケーションのいくつかの他の部分で使用されます。だから、私はこの "目に見えるルール"を一箇所に定義したいと思っています(DRY原理)。私は、次のプロパティに
public static Expression<Func<SubTable2, bool>> VisibleOnlyExpression => sub2 => sub2.Status == "Visible";
を書かれており、これがInternal .NET Framework Data Provider error 1025.
を述べ、私に例外をスロー
var query1 = dbContext.MainTable.Where(m => m.MainId == _mainId).SelectMany(sub => sub.SubTable1)
.Select(sub1 => new
{
sub1.CategoryName,
VisibleDivisions = sub1.SubTable2
.Where(VisibleOnlyExpression.Compile())
.Select(sub2 => new
{
/* select only what needed */
})
});
に私のクエリを変更したFunc<SubTable2, bool>
を期待しているところのよう
。 同じエラーで既に.Where(VisibleOnlyExpression.Compile())
に変更しようとしました。
これは、EntityFramework
がこれをSQL
にトランスレートしようとしているためです。
私の質問は:どのようにして、コード内の単一の場所(DRY)に定義された "フィルタルール"をWhere
- 、Select
- 、...で使用できるようにすることができますかIQueryable
と内部(サブ)クエリの場合はICollection
? IsAwesome
-ruleだけ素晴らしいメインのエントリを取得するために、後でサブ選択でICollection<MainTable>
にフェッチするIQueryable<MainTable>
に最初に呼び出されたのに対し、
var query = dbContext.MainTable
.Where(IsAwesome)
.SelectMany(s => s.SubTable1.Where(IsAlsoAwesome))
.Select(sub => new
{
Sub1sub2s = sub.SubTable2.Where(IsVisible),
Sub2Mains = sub.MainTable.Where(IsAwesome)
});
:
私のような何かを書くことができるようにするのが大好きです特定のSubTable2エントリに関連する素晴らしいメインエントリのみ。しかし、MainTableエントリをすばらしいものとして定義するルールは、どこで呼び出すかにかかわらず同じです。
解決策には表現木の使用法とその操作方法が必要なので、単純なSQLに翻訳できるようになると思いますが、まずは正しいアイデアやポイントを得ることができません。
// You forgot to access ".Status" in your code.
// Also you don't have to use "=>" to initialize "IsVisible". Use the regular "=".
public static Expression<Func<SubTable2, bool>> IsVisible = sub2 =>
sub2.Status == "Visible";
...
VisibleDivisions = sub1
.SubTable2
// Don't call "Compile()" on your predicate expression. EF will do that.
.Where(IsVisibleOnly)
.Select(sub2 => new
{
/* select only what needed */
})
[LinqKit](http://www.albahari.com/nutshell/linqkit.aspx)のようなサードパーティライブラリが必要です。 –
LinqKitで試してみました。同じ例外がスローされます。何か案は? – KingKerosin