模拟交叉上下文连接 - LINQ / C#

时间:2009-05-22 15:06:03

标签: c# entity-framework linq datacontext

问题在于:

我有2个数据上下文,我想加入。现在我知道LINQ不允许从一个上下文到另一个上下文的连接,我知道2个可能的解决方案是创建单个datacontext或者有2个单独的查询(这就是我现在正在做的事情)。但是,我想要做的是“模拟”一个连接。

这是我尝试过的。

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();
    }
}

3 个答案:

答案 0 :(得分:13)

也许这样的事情可以让你开始朝着正确的方向前进。我根据您的列名创建了一个具有相似列的模拟数据库,并获得了一些结果。

    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();
    }
}

希望这有帮助!

答案 1 :(得分:3)

这是我们找到的“解决方法”......

我们手动从其他数据库中构建我们的表,如果它们在同一台服务器上,那么我们将表名前缀为:

<DatabaseName>.<SchemaName>.<YourTableName>

如果它们位于链接服务器上,那么您还必须在其前面加上服务器名称:

<ServerName>.<DatabaseName>.<SchemaName>.<YourTableName>

这将允许你进行连接并仍然返回一个未执行的IQueryable ......这就是我们想要的。另外两种方法涉及加入内存IEnumerables,这意味着你在进行连接之前拉出所有记录(上面)并使用一个有限制的contains方法进行IQueryable连接......

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

答案 2 :(得分:0)

我赞成创建一个单独的数据上下文,其中只包含您要加入的两个表。但我想你可以在第二个上下文中维护一个临时表(包含来自第一个上下文的数据),然后加入临时表。