C# 模拟跨上下文连接——LINQ/C

C# 模拟跨上下文连接——LINQ/C,c#,entity-framework,linq,datacontext,C#,Entity Framework,Linq,Datacontext,问题是: 我有两个数据上下文,我想对它们进行连接。现在我知道LINQ不允许从一个上下文连接到另一个上下文,我知道有两种可能的解决方案,要么创建一个datacontext,要么创建两个独立的查询,这就是我现在要做的。然而,我想做的是模拟一个连接 这是我试过的 using (var _baseDataContext = Instance) { var query = from a in _baseDataContext.Account.ACCOUNTs whe

问题是:

我有两个数据上下文,我想对它们进行连接。现在我知道LINQ不允许从一个上下文连接到另一个上下文,我知道有两种可能的解决方案,要么创建一个datacontext,要么创建两个独立的查询,这就是我现在要做的。然而,我想做的是模拟一个连接

这是我试过的

using (var _baseDataContext = Instance)
{
    var query = from a in _baseDataContext.Account.ACCOUNTs
                where a.STR_ACCOUNT_NUMBER.ToString() == accountID
                join app in _baseDataContext.Account.APPLICATIONs on a.GUID_ACCOUNT_ID equals
                            app.GUID_ACCOUNT
                join l in GetLoans() on app.GUID_APPLICATION equals l.GUID_APPLICATION
                select l.GUID_LOAN;

    return query.Count() > 0 ? query.First() : Guid.Empty;
}

private static IQueryable<LOAN> GetLoans()
{
    using (var _baseDataContext = Instance)
    {
        return (from l in _baseDataContext.Loan.LOANs
                select l).AsQueryable();
    }
}
在运行时我得到的是

System.InvalidOperationException:查询包含对在不同数据上下文中定义的项的引用

编辑:

工作解决方案:

using (var _baseDataContext = Instance)
{
    var query = from a in _baseDataContext.Account.ACCOUNTs
                where a.STR_ACCOUNT_NUMBER.ToString() == accountID
                join app in _baseDataContext.Account.APPLICATIONs on a.GUID_ACCOUNT_ID equals
                           app.GUID_ACCOUNT
                join l in GetLoans() on app.GUID_APPLICATION equals l.GUID_APPLICATION 
                select l.GUID_LOAN;

     return (query.Count() > 0) ? query.First() : Guid.Empty;
}

private static IEnumerable<LOAN> GetLoans()
{
    using (var _baseDataContext = Instance)
    {
        return (from l in _baseDataContext.Loan.LOANs
                select l).AsQueryable();
    }
}

我倾向于创建一个单独的数据上下文,其中只包含要连接的两个表。但是我想您可以在第二个上下文中维护一个临时表,其中包含第一个上下文中的数据,然后加入临时表。

也许类似的内容可以让您从正确的方向开始。我根据您的列名创建了一个包含类似列的模拟数据库,并得到了一些结果

    class Program
{
    static AccountContextDataContext aContext = new AccountContextDataContext(@"Data Source=;Initial Catalog=;Integrated Security=True");
    static LoanContextDataContext lContext = new LoanContextDataContext(@"Data Source=;Initial Catalog=;Integrated Security=True");

    static void Main()
    {

        var query = from a in aContext.ACCOUNTs
                    join app in aContext.APPLICATIONs on a.GUID_ACCOUNT_ID equals app.GUID_ACCOUNT
                    where app.GUID_APPLICATION.ToString() == "24551D72-D4C2-428B-84BA-5837A25D8CF6"
                    select GetLoans(app.GUID_APPLICATION);

        IEnumerable<LOAN> loan = query.First();
        foreach (LOAN enumerable in loan)
        {
            Console.WriteLine(enumerable.GUID_LOAN);
        }

        Console.ReadLine();
    }

    private static IEnumerable<LOAN> GetLoans(Guid applicationGuid)
    {
        return (from l in lContext.LOANs where l.GUID_APPLICATION == applicationGuid select l).AsQueryable();
    }
}

希望这有帮助

这是我们找到的解决方案

我们从另一个数据库手动构建表,如果它位于同一台服务器上,则在表名前面加上前缀:

<DatabaseName>.<SchemaName>.<YourTableName>
如果它们位于链接服务器上,则必须在其前面加上服务器名称:

<ServerName>.<DatabaseName>.<SchemaName>.<YourTableName>
这将允许您执行联接,但仍然返回未执行的IQueryable。。。这就是我们想要的。中的其他两种方法包括加入内存IEnumerables,这意味着在执行上述连接之前,您将为每个IEnumerables提取所有记录,并使用包含方法执行IQueryable连接,但该方法有一些限制


希望将来DataContext的构建足够智能,能够知道如果服务器被链接,那么您可以在两个不同的服务器之间进行连接。

我以前尝试过返回IEnumerable,但收到了预期的强制转换错误。但是,我没有想到返回IEnuerable AsQueryable。这种方法的一个潜在问题是,您没有进行纯连接,因此,如果您需要在贷款上下文中添加另一个连接,您将无法从我看到的内容中进行连接。好的,我已经解决了。我们可以删除方法join上的where子句,而不是从方法中执行select,只执行纯join。这里的诀窍是方法必须返回IEnumerable.AsQueryable这允许我们进行跨上下文连接,到目前为止,我没有看到任何性能影响。创建一个单独的datacontext,其中可能只需要两个表,但是这不是一个孤立的需要,它只是需要此解决方案的一个示例。我希望避免每次需要满足这个需求时都创建一个孤立的datacontext。虽然这是一个好主意,但在这种情况下,这不是一个选项。不过,谢谢你的建议。