2

結合したい複数のクエリがあり、全体をコンパイルします。コンパイルされていないクエリは正常に実行されますが、「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例外がスローされます。

4

2 に答える 2

1

私は同じ問題を抱えていましたが、IQueryable<> を返すインライン静的メソッド呼び出しを分離して、この遅延クエリを変数に格納し、それを参照するようにしました。

これは Linq to SQL のバグだと思いますが、少なくとも妥当な回避策があります。

于 2010-10-26T15:58:25.603 に答える
0

私の推測では、linq コンパイラは IQueryable を返すメソッドを理解していません。

それをコンパイルするには、これらのメソッドはおそらく何らかの形式の Expression<> を返す必要があります。

于 2010-07-08T18:16:59.890 に答える