一个上下文引用 LINQ 查询引发多个引用异常 - BUG?

Posted

技术标签:

【中文标题】一个上下文引用 LINQ 查询引发多个引用异常 - BUG?【英文标题】:One context reference LINQ query throws multiple references exception - BUG? 【发布时间】:2014-12-18 12:02:27 【问题描述】:

我正在使用以下代码:

using(MainEntities mainContext = new MainEntities())

    return (from member in mainContext.aspnet_Membership
            where adminGroupUserIDs.Contains(member.UserId)
            select new
            
                FullName = member.FirstName + " " + member.LastName,
                UserName = (from user in mainContext.aspnet_Users
                            where user.UserId == member.UserId
                            select user.UserName)
            ).ToList(); 

其中adminGroupUserIDs 是一个IQueryable<GUID>,它由对MainEntities 的不同实例的查询形成。

使用此查询 LINQ 抱怨:

指定的 LINQ 表达式包含对与不同上下文关联的查询的引用。

有什么想法吗?

【问题讨论】:

我不确定后台发生了什么,但也许您需要创建另一个 MainEntities 实例以在内部表达式中使用 (from user in mainContext.aspnet_Users ...) - 请参阅 ***.com/questions/7332920/… @Pzyon:恰恰相反。如果他这样做了,那么他肯定会得到那个错误。 【参考方案1】:

我无法从您在此处显示的代码中确定,但我很确定 adminGroupUserIDs 是另一个尚未检索到的查询的结果,并且是使用 @987654322 的不同实例创建的@。您不能混合来自不同上下文的查询,甚至不能混合来自同一上下文类的不同实例。尝试将其更改为以下内容:

var loadedAdminGroupUserIDs = adminGroupUserID.ToArray();

using(MainEntities mainContext = new MainEntities())

    return (from member in mainContext.aspnet_Membership
            where loadedAdminGroupUserIDs.Contains(member.UserId)
            select new
            
                FullName = member.FirstName + " " + member.LastName,
                UserName = (from user in mainContext.aspnet_Users
                            where user.UserId == member.UserId
                            select user.UserName)
            ).ToList(); 

【讨论】:

阿隆的优点。我完全忽略了adminGroupUserIDs!最初,我发布的查询使用存储库模式方式的存储库构建查询,即使用MembershipRepository.AllUsersRepository.All。但后来我收到了上面发布的错误并切换到using 块。但我认为你成功了,因为 adminGroupUserIDs 是并且 IQueryable 是由第三个存储库构建的! 您修复的问题是loadeAdminGroupUserIDs 现在在内存中,我一定会收到Unable to create a constant value of type 错误,因为查询在数据库中。最后我不得不加入一个连接,这可能更接近原生 SQL。但我仍然确信我可以实施您的解决方案。我错过了什么? 另一点。我把自己绊倒了,因为我想从我的存储库构建我的查询,每个存储库都代表一个表。使用这种模式,每个 Repo 都会实例化一个 MainEntities 上下文。从这个案例中收集,我是否可以推断出 Repo 模式仅在仅对一个表执行查询时才有用?我是否错误地实施了该模式?这可能是另一个 SO 问题。 假设adminGroupUserIDsIQueryable<int>(或<long>),我上面的建议将导致实体框架将.Contains(...) 转换为IN 表达式,这样如果adminGroupUserIDs包含三个 ID,5、18 和 42,这三个值的内存数组将由第一行创建,然后 EF 将识别这一点并创建以下 SQL:WHERE UserId IN (5, 18, 42),它也可以不使用单个数据上下文。但是,如果您希望所有这些都发生在数据库中,那么您必须使用单个数据上下文(有或没有连接)。 对不起,Allon,我错过了一个重点。 adminGroupUserIDs 是一个 GUID :(。这解释了为什么 .Contains 失败了。感谢您的洞察力。将编辑我的问题。【参考方案2】:

尝试将.FirstOrDefault() 添加到您的子查询中。

using(MainEntities mainContext = new MainEntities())

    return (from member in mainContext.aspnet_Membership
            where adminGroupUserIDs.Contains(member.UserId)
            select new
            
                FullName = member.FirstName + " " + member.LastName,
                UserName = (from user in mainContext.aspnet_Users
                            where user.UserId == member.UserId
                            select user.UserName).FirstOrDefault()
            ).ToList(); 

【讨论】:

是的,这是查询中的另一个错误,很好!虽然我不明白它是如何导致上述错误的。 好收获。不幸的是,问题正是@AllonGuralnek 建议的,我包括了 3 个!我的查询中有不同的MainEntity 上下文(查询本身中有2 个,adminGroupUserIDs 是来自第三个MainEntities 上下文的IQueryable)。这就是使用存储库模式的现实。我需要 3 个不同的存储库,每个存储库都实例化了一个 MainEntities 上下文。

以上是关于一个上下文引用 LINQ 查询引发多个引用异常 - BUG?的主要内容,如果未能解决你的问题,请参考以下文章

对 ITVF 的引用会引发“在前一个操作完成之前在此上下文上启动的第二个操作”异常

linq 在查询表达式中处理异常

错误:“指定的 LINQ 表达式包含对与不同上下文关联的查询的引用”

指定的 LINQ 表达式包含对与不同上下文关联的查询的引用

Linq Lambda 错误:指定的 LINQ 表达式包含对与不同上下文关联的查询的引用

包含对与不同上下文关联的查询的引用的 LINQ 表达式