Имитация кросс-контекстных объединений - LINQ/С#

Здесь проблема:

У меня есть 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: запрос содержит ссылки на элементы, определенные в другом контексте данных.

EDIT:

Рабочее решение:

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

Ответ 1

Возможно, что-то вроде этого поможет вам начать работу в правильном направлении. Я создал базу данных с похожими столбцами на основе ваших имен столбцов и получил некоторые результаты.

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

Надеюсь, это поможет!

Ответ 2

Это "работа вокруг", которую мы нашли...

Мы построили наши таблицы из другой базы данных вручную, и если они находятся на одном сервере, мы префиксное имя таблицы:

<DatabaseName>.<SchemaName>.<YourTableName>

если они находятся на связанном сервере, тогда вы также должны указать его имя сервера:

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

Это позволит вам делать соединения и все еще возвращать не выполненные IQueryable... что мы и хотели. Другие 2 способа включают в себя объединение IEnumerables в памяти, что означает, что вы извлекаете все записи для каждого из них перед выполнением объединения (см. Выше) и выполняете объединение IQueryable с использованием метода contains, который имеет ограничения...

Надеюсь, в будущем DataContext будет построен достаточно умным, чтобы знать, что если серверы связаны, вы можете делать соединения между двумя разными.

Ответ 3

Я выступаю за создание отдельного контекста данных, который содержит только две таблицы, которые вы хотите присоединиться. Но я предполагаю, что вы могли бы сохранить временную таблицу (содержащую данные из первого контекста) во втором контексте, а затем присоединиться к временной таблице.