Имитация перекрестных контекстных соединений - LINQ / C # - PullRequest
20 голосов
/ 22 мая 2009

Вот проблема:

У меня есть 2 контекста данных, к которым я хотел бы присоединиться. Теперь я знаю, что LINQ не разрешает соединения из одного контекста в другой, и я знаю, что 2 возможных решения - создать один текстовый текст или иметь 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();
    }
}

Ответы [ 3 ]

13 голосов
/ 22 мая 2009

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

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

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

3 голосов
/ 22 мая 2009

Это «обходной путь», который мы нашли ...

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

<DatabaseName>.<SchemaName>.<YourTableName>

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

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

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

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

0 голосов
/ 22 мая 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...