在select中使用PredicateBuilder

时间:2011-04-08 12:14:42

标签: c# .net linq linq-to-sql

我正在为我的应用程序创建一个Ad-hoc报告功能。 我使用PredicateBuilder作为“Where”部分,但现在当我试图在“选择”部分使用它时,我无法成功。

代码示例:

   IQueryable<User> usersQuery = db.Users.AsQueryable();

    var where = PredicateBuilder.True<User>();
    //sample for the users query
    where = where.And(p => p.Enabled);


    var selectOrders = PredicateBuilder.True<UserOrder>();
    //sample for a query inside user orders
    selectOrders = selectOrders.And(p => p.Amount > 10);

    usersQuery = usersQuery.Where(where); //work
    var query = (from a in usersQuery
         select new
                {
                FirstName = a.FirstName,
                TotalOrders = a.UserOrders.Where(selectOrders).Count() //could not compile                                                                                               
                }).AsQueryable();

我认为你不能做到

.Select("new (TotalOrders = UserOrders.Where(BetAmount > @0).Count()")

在DynamicLinq中但我无法使用它因为我在'select'中调用了一些sql用户定义的函数而DynamicLinq不支持它。

2 个答案:

答案 0 :(得分:3)

我认为问题在于,Linq to SQL不支持查询所需的子查询。这就是为什么你的案例中的导航属性UserOrders没有实现IQueryable并且无法在其上运行查询。

我可能错了。 但这证明我是正确的:http://blog.robustsoftware.co.uk/2009/01/why-linq-to-sql-is-not-proper-orm.html

您应该使用更好的ORM,例如Entity Framework。

答案 1 :(得分:0)

这样的解决方法怎么样?您已根据架构更改了连接条件

var where = PredicateBuilder.True<User>();
//sample for the users query
where = where.And(p => p.Enabled);

var selectOrders = PredicateBuilder.True<UserOrder>();
//sample for a query inside user orders
selectOrders = selectOrders.And(p => p.Amount > 10);

var usersQuery = from u in db.Users.Where(where)
                 join o in db.UserOrders.Where(selectOrders) 
                        on u.UserId equals o.UserId
                 group o by u into groupedOrders
                 select new
                 {
                    FirstName = groupedOrders.Key.FirstName,
                    TotalOrders = groupedOrders.Count()                                                                                              
                 };