結合したい複数のクエリがあり、全体をコンパイルします。コンパイルされていないクエリは正常に実行されますが、「InvalidOperationException: 'UserQuery+Foo' のメンバー アクセス 'Int32 Id' は、タイプ 'System.Linq.IQueryable`1[UserQuery+Foo] では正当ではありません。」同じクエリをコンパイルして実行すると、例外がスローされます。
これを修正するにはどうすればよいですか?
void Main()
{
var db = new MyDataContext( "..." );
Expression < Func < DataContext, int, IQueryable < Foo > > > queryExpression = (DataContext dc, int unused) =>
from ab in GetA(dc).Union( GetB(dc) )
group ab by new { ab.Id, ab.Name } into grp
select new Foo
{
Id = grp.Key.Id,
Name = grp.Key.Name,
Total = grp.Count()
};
var final = CompiledQuery.Compile ( queryExpression );
var result1 = queryExpression.Compile () (db, 0); // calling the original query works fine
var result2 = final (db, 0); // calling the compiled query throws an exception
}
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
public int Total { get; set; }
}
IQueryable<Foo> GetA( DataContext db )
{
return from b in db.GetTable<Bar>()
where b.IsActive
select new Foo { Id = b.Id, Name = b.Name };
}
IQueryable<Foo> GetB( DataContext db )
{
return from b in db.GetTable<Bar>()
where !b.IsActive
select new Foo { Id = b.Id, Name = b.Name };
}
編集
ユニオンとグループ化は無関係のようです。これらの要素をクエリから削除しても、コンパイル時に例外が発生します。
Expression < Func < DataContext, int, IQueryable < Foo > > > queryExpression = (DataContext dc, int unused) =>
from a in GetA(dc)
select new Foo
{
Id = a.Id,
Name = a.Name,
Total = 42
};
への呼び出しをGetA(dc)
withに置き換えdc.GetTable<Bar>()
て where 句を追加すると、問題が修正されます。
では、このように個別のクエリを一緒に接続することは、コンパイルされたクエリでは不可能ですか?
編集#2
ジェームズの答えは的を射ていた。クエリをさらに単純化すると、根本的な問題が明らかになります。
Expression < Func < DataContext, int, IQueryable < Foo > > > queryExpression = (DataContext dc, int unused) =>
from a in GetA(dc)
select a;
このクエリはスローしますNotSupportedException: Method 'System.Linq.IQueryable``1[UserQuery+Foo] GetA(System.Data.Linq.DataContext)' has no supported translation to SQL.
GetA への呼び出しを別の変数割り当てに引き出し、その変数をクエリで使用すると、InvalidOperationException: Sequence contains more than one element
例外がスローされます。