LINQ to Entities不识别方法IsUserInCc。

3

我的代码:

elections = elections.Where(e => e.Creator == Username || e.Approver == Username || IsUserInCc(e.Cc,Username))
    .OrderBy(e => e.Status)
    .ThenByDescending(e => e.Group);
var test = elections.FirstOrDefault();

private bool IsUserInCc(string cc, string username)
{
    var ccList = cc.Split(';');
    if (ccList.Contains(username))
        return true;
    return LDAPUtility.Instance.IsUserInGroup(ccList.ToList(), username);
}

错误:

LINQ to Entities 不认识 IsUserInCc 方法。

通过许多帖子,我可以理解为什么会出现错误。基本上,IsUserInCc 在 SQL 执行中不可用。我需要以某种方式将其转换回 C# 以处理它。

LINQ to Entities 不认识我的方法

LINQ to Entities 不认识查询中的方法

LINQ to Entities 不认识 'System.String ToString(Int32)' 方法

然而,在我的具体情况下,最好的方法是什么?


你有任何异常或者类似的东西吗? - AmirReza-Farahlagha
请访问上一个答案! - AmirReza-Farahlagha
LDAPUtility.Instance.IsUserInGroup(ccList.ToList(), username) 的目的是什么?如果可以删除或重新设计它,查询可能与 IQueryable 兼容。 - Mel Gerats
5个回答

2
您需要先转换为list。另外请注意,elections必须能够容纳一个list才能运行。
elections = elections.ToList().Where(e => e.Creator == Username || e.Approver == Username || IsUserInCc(e.Cc,Username))
.OrderBy(e => e.Status)
.ThenByDescending(e => e.Group);

1

对于你编写的函数,无法在 Queryables 上使用。你需要将其转换为内存中的 list,然后使用你的函数应用所需的过滤器。


那又怎样,如果“选举”包含一百万条记录呢? - Gert Arnold
然后,您需要将此自定义函数中的任何操作转换为SQL函数。没有其他方法来处理这个。 - Sarav
但是由于 string.Split 的存在,这是不可能的。我认为沿着“先获取,然后过滤”的思路没有可行的方式。建议OP更改数据结构,如 此答案 所建议。 - Gert Arnold
@GertArnold 但那将是一项设计更改。但如果我没错的话,这里涉及的是一个电子邮件ID分隔符(;)文本框字符串,无法再进行更深层次的规范化。 - Sarav
当然可以!IDs 不应该存储为分号分隔的字符串。 - Gert Arnold
@Gert LDAPUtility.Instance.IsUserInGroup 对我来说似乎是一个绊脚石(如果它的名字意味着这个)。而且,由于它与“包含”条件进行了“或”运算,整个条件看起来无法转换为SQL,无论是否进行适当的数据规范化。因此,在这种特殊情况下,回答者所建议的可能是唯一的解决方案。 - Ivan Stoev

1
你遇到问题的根本原因是你的底层数据没有被适当地规范化。你需要将你的CC放在一个集合中,而不是作为一个单独的分隔字符串。
在SQL中,你需要添加一个名为CC的新表,并将每个用户名放入其中,并将其链接回选举。或者,如果它是一个内存集合,在其Getter中添加一个新属性,它将为您执行拆分操作。
无论哪种方式,这样你就不会遇到这种问题。如果你的数据结构不正确,那么你在堆栈的更高层面上会遇到问题。

0

当您想要使用 Linq数据库 发送 请求 时:

var query = listData.Where(x=>x.Id == 123);

这个query的类型是IQueryable,这意味着你的查询还没有被Executed

现在你正在将数据作为IQueryable发送到方法中,无法处理你的数据,你必须使用像Tolist()ToListAsync()或类似的方法来Execute它。

最好的方法是从数据库获取数据而不使用该方法,之后再执行你的查询,然后可以运行此方法。

祝你好运。


0
你可以试试这样写:
 elections = elections.Where(e => e.Creator == Username || e.Approver == Username).Tolist().Where(e => IsUserInCc(e.Cc,Username))
.OrderBy(e => e.Status)
.ThenByDescending(e => e.Group);

var test = elections.FirstOrDefault();

变量test等于elections的第一个元素。

private bool IsUserInCc(string cc, string username)
{
    var ccList = cc.Split(';');
    if (ccList.Contains(username))
        return true;
    return LDAPUtility.Instance.IsUserInGroup(ccList.ToList(), username);
}

这是不同的:它将最后一个 || 转换为 && - Gert Arnold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接