【发布时间】:2010-07-08 15:23:19
【问题描述】:
我想将多个查询合并在一起,然后编译整个内容。未编译的查询运行良好,但“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) 的调用替换为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 异常。
【问题讨论】:
标签: linq-to-sql union compiled-query linq.compiledquery