如何在 LINQ 中实现客户端评估?

问题描述 投票:0回答:1

我不明白 StackOverflow 的代码格式化功能。

我正在尝试进行客户端评估,但似乎没有进行。如果查看输出,它仍然具有 AsEnumerable 查询中的对象。不应该只是结果吗?我不明白为什么它仍然试图将其写入查询中。还有其他方法可以启用客户端评估吗?

var groups = Groups!.Where(g => g.Selected).Select(g => (Group)g.Object!).AsEnumerable();
SelectedGroupPosts.AddRange(from p in DB.Post
                            join u in DB.User
                               on p.UserId equals u.Id
                            join gm in DB.GroupMember
                                on u.Id equals gm.UserId
                            join g in DB.Group
                                on gm.GroupId equals g.Id
                            where groups.Contains(g)
                            select p);

System.InvalidOperationException
  HResult=0x80131509
  Message=The LINQ expression 'DbSet<Group>()
    .Join(
        inner: DbSet<GroupMember>(), 
        outerKeySelector: g1 => (object)g1.Id, 
        innerKeySelector: g2 => (object)g2.GroupId, 
        resultSelector: (g1, g2) => new TransparentIdentifier<Group, GroupMember>(
            Outer = g1, 
            Inner = g2
        ))
    .Join(
        inner: DbSet<User>(), 
        outerKeySelector: ti2 => (object)ti2.Inner.UserId, 
        innerKeySelector: u0 => (object)u0.Id, 
        resultSelector: (ti2, u0) => new TransparentIdentifier<TransparentIdentifier<Group, GroupMember>, User>(
            Outer = ti2, 
            Inner = u0
        ))
    .Where(ti3 => ti3.Inner.Email == __Email_0)
    .Where(ti3 => new ClickSelectorModel{ 
        Label = ti3.Outer.Outer.Name, 
        Object = ti3.Outer.Outer 
    }
    .Selected)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
  Source=Microsoft.EntityFrameworkCore
c# .net linq
1个回答
0
投票

与其使用像

where ObjectCollection.Contains(objectFromQuery)
这样的条件,我相信使用像
where ObjectIdList.Contains(IdFromQuery)
这样的条件会更好。

更具体地说,如果您使用

var groupIdList = ... .Select(g => g.Id).ToList();
构建组 ID 列表,则后续 LINQ 查询可以删除
join g ...
并使用条件
where groupIdList.Contains(gm.GroupId)

这应该可以干净地翻译并在服务器端运行。你真的不想在客户端做这个。

尝试:

var groupIdList = Groups!.Where(g => g.Selected).Select(g => g.Id).ToList();
SelectedGroupPosts.AddRange(from p in DB.Post
                            join u in DB.User
                               on p.UserId equals u.Id
                            join gm in DB.GroupMember
                                on u.Id equals gm.UserId
                            where groupIdList.Contains(gm.GroupId)
                            select p);
© www.soinside.com 2019 - 2024. All rights reserved.