使用Linq/Lambda,如何在两个DBContext中连接两个或多个表格?

5
我遇到了这样的错误:指定的LINQ表达式包含与不同上下文相关联的查询的引用。
var employee = new ApplicationDbContext().Employee;
var otherTable = new OtherDbContext().OtherTable;

var returnValue = (from e in employee
                        join o in otherTable on e.Id equals o.Id
                        select new
                        {
                            e.Name,
                            e.Address,
                            o.Others
                        });

任何解决方案吗? 谢谢!

我不确定您是否可以跨两个上下文进行连接。EF 必须以某种方式将其转换为 SQL 查询。 - garryp
3
无法同时查询两个上下文,请参阅此问题/答案:https://dev59.com/RW855IYBdhLWcg3wilCD - Terence
员工表或其他表中有很多数据吗? - Adil Mammadov
注释是正确的。请注意,join方法的内部类型将始终为IEnumerable,因此只需将第二个上下文(内部)的实体加载到一个IEnumerable<otherTable>变量中即可。 https://msdn.microsoft.com/zh-cn/library/vstudio/bb534644(v=vs.100).aspx - Brett Caswell
不知怎么的,很快就会有大量数据。所以我认为如果在第二个上下文中查询所有记录(类似于.ToList()),性能会受到影响。谢谢! - jmvtrinidad
3个回答

4

项目中的所有查询都使用linq或lambda,如果在这个特定的查询中使用原始SQL,则会不一致。 - jmvtrinidad
如果我们在SP上进行操作并创建一个链接服务器,而不是调用.ToList()来查询所有内容,那将更好。因此我会接受这个答案。 - jmvtrinidad

0
最佳解决方案是使用一个DbContext来处理两个实体。这样,EF可以轻松地在它们之间进行连接。您可以创建另外两个不同的实体,只包含您想要的字段。如果您担心维护重复类型,请考虑在它们之间创建接口(SOLID的接口隔离原则)。这样,如果您更改属性或字段,首先通过接口进行更改,它将强制您纠正重复类型。
假设您无法更改现有的ApplicationDbContext和OtherDbContext,您可以创建第三个DbContext和两个重复的模型,如下所示:
interface IEmployee { string Name { get; } string Address { get; } }
interface IOtherTable { IEnumerable Others { get; } }
public class Employee : IEmployee { /* your existing class that may have more field*/ }
public class OtherTable : IOtherTable { /* your existing class that may have other fiels*/ }

public class Employee2 : IEmployee { /* Making this a subclass in a controller or something is preferred */ }
public class OtherTable2 : IOtherTable { /* Making this a subclass in a controller or something is preferred */ }
public sealed class CombinedDbContext {
    public DbSet<Employee2> { get; set; }
    public DbSet<OtherTable2> { get; set; }
}

现在你可以安全地完成这个任务,而不需要使用hacky代码...

var con = new CombinedDbContext();
var employee = con.Employee;
var otherTable = con.OtherTable;

var returnValue = (from e in employee
                    join o in otherTable on e.Id equals o.Id
                    select new
                    {
                        e.Name,
                        e.Address,
                        o.Others
                    });

-1
List<Employee> empList = new ApplicationDbContext().Employee.ToList();
List<OtherTable> othrList= new OtherDbContext().OtherTable.ToList();

var returnValue = (from e in empList 
                        join o in othrList on e.Id equals o.Id
                        select new
                        {
                            e.Name,
                            e.Address,
                            o.Others
                        });

尝试这个,它会起作用的......


谢谢回复! .ToList()正在查询所有记录,所以查询所有记录可能会很费力。 你觉得呢? 还有其他解决方案吗? - jmvtrinidad
Manish,谢谢,但实例化每个实体仅用于执行连接操作是一个不好的想法。 - RashadRivera

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