Ошибка: «Указанное выражение LINQ содержит ссылки на запросы, связанные с различными контекстами» - PullRequest
58 голосов
/ 07 сентября 2011

Я получаю сообщение об ошибке, отображаемой в заголовке, из запроса LINQ, который включает две таблицы из двух разных файлов edmx. Вот запрос:

var query = (from a in db1.Table1
           join b in db1.Table2 on a.Id equals b.Id
           orderby a.Status
           where b.Id == 1 && a.Status == "new"
           select new
           {
               Id = a.Id,
               CompanyId = (from c in db2.Company
                            where s.Id == a.Id
                            select
                            new { c.CompanyId })
           });

db1 и db2 - это контексты, связанные с двумя разными файлами edmx. Как я могу преодолеть эту ошибку?

Ответы [ 3 ]

109 голосов
/ 07 сентября 2011

Вам нужно будет выполнить два запроса к базе данных:

var IDs =  (from a in db1.Table1 
            join b in db1.Table2 on a.Id equals b.Id 
            orderby a.Status 
            where b.Id == 1 && a.Status == "new" 
            select new a.Id).ToArray();

var query = from c in db2.Company
            join a in IDs on c.Id equals a.Id
            select new { Id = a.Id, CompanyId = c.CompanyId };

.ToArray() имеет решающее значение. Это предотвращает попытки EF выполнить комбинированный запрос (который завершится неудачей, поскольку он использует два разных контекста). Вы можете использовать .AsEnumerable(), если предпочитаете ленивую загрузку.


И ваш дополнительный вопрос:

Есть ли другой способ сделать запрос LINQ более оптимизированным? То есть, выполнить действие в одном запросе LINQ?

Чтобы исходный запрос был успешно выполнен, он должен использовать только один контекст данных, что означает, что все данные должны быть доступны из одного EDMX, что, в свою очередь, означает одну строку подключения. Это можно сделать несколькими способами:

  • Если обе таблицы находятся в одной базе данных, добавьте их обе в один EDMX.
  • Если они находятся в разных базах данных, но в одном и том же экземпляре, создайте представление для одной из баз данных, которое выбирается из таблицы в другой базе данных, затем добавьте локальную таблицу и представление в один EDMX.
  • Если они находятся на разных экземплярах / серверах, создали связанный сервер, затем создайте представление таблицы на связанном сервере, затем добавьте локальную таблицу и представление в один EDMX.
2 голосов
/ 07 сентября 2011

Вам либо нужно добавить вторую таблицу к модели первого контекста.Если это в нескольких базах данных, вам нужно выполнить вторичный поиск на стороне клиента, используя соединение Linq to Objects.

0 голосов
/ 04 августа 2018

Вы должны вручную создать EntityConnection, заполненный ресурсами всех .EDMX, которые вы хотите использовать. Вы можете сделать это, добавив соединение с app.config или программно. Затем вы можете создать DBContext, используя подготовленный EntityConnection.

метод а)

<add name="MyConnection"
connectionString="metadata=res://*/Entities.ModuleA.csdl|res://*/Entities.ModuleA.ssdl|res://*/Entities.ModuleA.msl|res://*/Entities.ModuleB.csdl|res://*/Entities.ModuleB.ssdl|res://*/Entities.ModuleB.msl;
provider=System.Data.SqlClient;provider connection string=&quot;MyConnectionString&quot;"
providerName="System.Data.EntityClient" />

using (EntityConnection oEntityConnection =
    new EntityConnection("name=MyConnection"))
{
    using(DbContext oDBContext = new DbContext(oEntityConnection))
    {
        //your code - available are entities declared in Entities.ModuleA and Entities.ModuleB
    }
}

метод б)

 using (EntityConnection oEntityConnection =
        new EntityConnection(new MetadataWorkspace(
        new string [] { 
"res://Entities.ModuleA/", 
"res://Entities.ModuleB/" 
},
        new Assembly[] { 
Assembly.GetAssembly(typeof(Entities.ModuleA.AnyType)),
Assembly.GetAssembly(typeof(Entities.ModuleB.AnyType)) 
}
        )))
    {
        using(DbContext oDBContext = new DbContext(oEntityConnection))
        {
            //your code - available are entities declared in Entities.ModuleA and Entities.ModuleB
        }
    }
...