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

Posted

技术标签:

【中文标题】Linq Lambda 错误:指定的 LINQ 表达式包含对与不同上下文关联的查询的引用【英文标题】:Linq Lambda Error : The specified LINQ expression contains references to queries that are associated with different contexts 【发布时间】:2021-11-12 05:37:00 【问题描述】:

我收到这个错误,我尝试了很多解决它,但我收到其他错误,有解决办法吗?

using (var contextDb1 = new Db1Context(System.Web.HttpContext.Current.Session["DB1ConnectionString"].ToString(), false))

    using (var contextDb2 = new Db2Context(System.Web.HttpContext.Current.Session["DB2ConnectionString"].ToString(), false))
       
        var messagesList = contextDb2.Messages
            .Select(m => new MessagesViewModel
            
                UserName = contextDb1.UsersInfo.FirstOrDefault(u=>u.Id == m.UserId).UserName,
                MessageId = m.MessageId,
                MessageText = m.MessageText,
                DateTime = m.DateTime
            )
            .ToList();

        return messagesList;   
    

【问题讨论】:

尝试通过 LINQ 和 EF 同步两个数据库? 在获取消息之前尝试获取用户定义类型列表中的 contextDb1.UsersInfo 并使用该列表获取用户名。 @SvyatoslavDanyliv 在第二个数据库(Db2)中,我有一个包含消息的表,其中包含编写消息的用户的 ID,但用户信息(例如用户名)在另一个数据库(Db1)中,并且我想显示带有用户名的消息...但出现上述错误 @Smits ,不好意思没看懂你,其实我试了很多办法都无济于事,不知道怎么办,能不能把上面的代码改正一下? 【参考方案1】:

您不能通过同一个 LINQ 查询来查询两个不同的数据库。但是您可以使用中间结果对数据库执行两个查询,然后合并结果。

using (var contextDb1 = new Db1Context(System.Web.HttpContext.Current.Session["DB1ConnectionString"].ToString(), false))
using (var contextDb2 = new Db2Context(System.Web.HttpContext.Current.Session["DB2ConnectionString"].ToString(), false))
   
    var rawMessages = contextDb2.Messages
        .Select(m => new 
        
            m.UserId
            m.MessageId,
            m.MessageText,
            m.DateTime
        )
        .ToList();

    var userIds = rawMessages.Select(x => xu.UserId);
    
    var usersInfo = contextDb1.UsersInfo.Where(u => userIds.Contains(u.Id))
        .Select(u =>  new 
        
            UserId = u.Id,
            UserName = u.UserName
        );

    var messageQuery = 
        from m in rawMessages
        join u in usersInfo.AsEnumerable() on m.UserId equals u.UserId into gj
        from u in gj.DefaultIfEmpty()
        select new MessagesViewModel
        
            UserName = u?.UserName,
            MessageId = m.MessageId,
            MessageText = m.MessageText,
            DateTime = m.DateTime
        ;
    
    var messagesList = messageQuery.ToList();

    return messagesList;   

【讨论】:

要考虑的另一种方法是将两个数据库上下文放入单独的方法中。创建调用这两个方法的第 3 个方法,然后在那里转换最终输出。如果不能保证这些查询始终可用,这可能有助于跟踪堆栈跟踪以了解失败的位置。

以上是关于Linq Lambda 错误:指定的 LINQ 表达式包含对与不同上下文关联的查询的引用的主要内容,如果未能解决你的问题,请参考以下文章

Lambda 表达式 LINQ 等效于 SQL 在同一表/变量上存在查询

如何在 LINQ lambda 中执行多个表之间的联接

错误:对于带有 from 的 Linq,“表达式树 lambda 可能不包含空传播运算符”

使用实体框架 4.1 进行多表连接,我应该使用 lambda 还是 LINQ?

2017-6-1 Linq表达式 Lambda 表达式

Lambda vs LINQ-“表达式总是错误的”