Linq通过List <t>(System.Collection.Generic.List)对象过滤IQueryable <t>(System.Data.Linq.DataQuery)对象?</t> </t>

时间:2010-04-19 08:21:36

标签: c# asp.net-mvc linq-to-sql list iqueryable

我的IQueryable系列是:

 // find all timesheets for this period - from db so System.Data.Linq.DataQuery
 var timesheets = _timesheetRepository.FindByPeriod(dte1, dte2);

我的列表行是:

 // get my team from AD - from active directory so System.Collection.Generic.List
 var adUsers = _adUserRepository.GetMyTeam(User.Identity.Name);

我希望只显示时间表集合中用户集合中存在的用户的时间表。

如果我使用标准的c#表达式,例如:

 var teamsheets = from t in timesheets
                  join user in adUsers on t.User1.username equals user.fullname
                  select t;

我收到错误“不支持返回自引用常量表达式的IQueryable”

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

Linq to Sql将尝试生成一个sql查询来表示整个表达式。这意味着它会尝试将广告用户集合作为参数传递给sql查询。如果用户太多,查询将达到参数限制(2100)并且无法执行。如果团队中没有那么多用户,那么您可以使用contains表达式,该表达式将转换为sql中的“IN”表达式。

这是史蒂文的建议:

string[] usernames = adUsers.Select(u => u.fullname).ToArray();

var teamsheets =
from t in timesheets
where usernames.Contains(t.User1.username)
select t;

以您尝试的方式使用连接的唯一方法是从数据库中检索所有时间表到内存中(使用timeheets var上的ToList),然后连接将在内存中进行。如果这比使用包含更好,或者由于团队规模而无法使用包含,则可能值得考虑。

答案 1 :(得分:3)

join结构不起作用,但您可以使用Contains方法。下一个片段可能会起到作用。

string[] usernames = adUsers.Select(u => u.fullname).ToArray();

var teamsheets =
    from t in timesheets
    where usernames.Contains(t.User1.username)
    select t;