【问题标题】:LINQ EF Join query from 2 different data context来自 2 个不同数据上下文的 LINQ EF 连接查询
【发布时间】:2015-11-04 17:24:54
【问题描述】:

我正在使用 LINQ 从我的 EF 上下文以及 Asp .Net Identity 2.0 中检索数据 - 两者都位于同一个 MS SQL Server 数据库中。

我的问题是 LINQ 将它们视为两种不同的数据上下文情况,无法处理查询。

"The specified LINQ expression contains references to queries that are associated with different contexts."

我想要实现的是从 EF 表中简单返回 10 个最重要的项目(我在代码摘录中跳过了这个),之前按 ASP .NET 标识表中的用户名排序。

我在 StackOverflow 上看到过一些此问题的案例,但我无法在我的案例中应用任何解决方案。

首选的解决方案当然是不下载所有表格数据并在服务器上进行排序。

有问题的查询:

var dbDataSorted = from entry in dbData
        join user in this.UserManager.Users
        on entry.UserId equals new Guid(user.Id)
        orderby user.UserName ascending
        select entry;
return dbDataSorted;

【问题讨论】:

  • 您可以使用 2 个不同的上下文进行基于服务器的连接,即使它们使用同一个数据库,每个上下文也需要了解查询中的所有表。
  • 这里实现的一个丑陋的方法是编写一个存储过程,它将连接两个数据库表其他选项在this答案中

标签: c# sql asp.net linq entity-framework


【解决方案1】:

我可以通过使用 AsEnumerable() 来解决这个问题。 YMMV。

在你的情况下:

var dbDataSorted = from entry in dbData.AsEnumerable()
    join user in this.UserManager.Users
    on entry.UserId equals new Guid(user.Id)
    orderby user.UserName ascending
    select entry;
return dbDataSorted;

【讨论】:

  • AsEnumerable() 之所以有效,是因为它强制该部分查询在客户端执行。只要 dbData 不返回大量记录,它就可以在大多数情况下运行良好。
  • 这解决了我的问题。我从两个不同的 dbcontexts 加入,一个继承 IdentityDbContext,另一个没有,并且需要通过用户 ID 加入。谢谢。
  • 要使其正常工作,您需要在连接字符串中启用“MultipleActiveResultSets=true”参数;否则你会得到一个“已经有一个打开的 DataReader 与此命令关联,必须先关闭”错误。
【解决方案2】:

LINQ 和 EF 非常酷。但有时,它的抽象并不能提供您所需要的。

回到基础,手动编写查询,将其放入字符串中,使用 SqlQuery 方法针对yourcontext.YourDbSet 运行它,然后就完成了。

var query = @"SELECT * FROM dbData as entry
              INNER JOIN Users
              ON entry.UserId = Users.Id
              ORDER BY Users.Username";

yourcontext.dbData.SqlQuery(query);

如果提供给您的抽象不能满足您的需求,那么滥用抽象来做一些奇怪的事情远不如使用较低级别的接口那么清楚。

【讨论】:

  • 这是我决定使用的解决方案。您的论点令人信服,并且按预期工作。谢谢。
【解决方案3】:

您不能在一个查询中使用 Linq to Entities 和 Linq 来反对。这是因为当你对 IQueryable 接口的实例进行查询时,查询将被转换为 SQL,而在 SQL 中你不能使用任何 IEnumerable 集合。所以你应该从数据库中获取数据(例如 dbData.AsEnumerable())。 但是,如果您想在SQL Server 端 完成所有工作,最简单的方法是创建sql 过程并将用户表作为参数传递。将 users 表作为 xml 传递并在服务器端的过程中对其进行解析的最简单方法。

【讨论】:

  • 添加 .AsEnumerable() 会给我从 'System.Collections.Generic.IEnumerable<...>' 到 'System.Linq.IQueryable<...>' 的转换错误。也就是说,我不想从 db 下载所有数据,所以这不是我要实施的解决方案。无论如何感谢您的重播。
  • 我编辑了答案,如果你不想加载所有数据,你应该以某种方式将你的数据上传到 sql server,在那里你可以做任何你想做的事情。我认为仅通过 linq 是不可能的。但是您可以将过程用作实体
【解决方案4】:

如果您使用 ASP.NET Identity 2 代码优先,那么您的 DbContext 可能继承自 IdentityDbContext&lt;&gt;,因此您可以直接从上下文访问 Users 表。您无需使用UserManager 来访问用户。

【讨论】:

    猜你喜欢
    • 2013-07-04
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-25
    相关资源
    最近更新 更多