Почему я получаю Указанное выражение LINQ содержит ссылки на запросы, связанные с различными контекстами? - PullRequest
0 голосов
/ 03 октября 2018

Исключение:
System.NotSupportedException: 'Указанное выражение LINQ содержит ссылки на запросы, связанные с различными контекстами.'

Код:

IEnumerable<EntityIdName> entitiesIDs = 
    (from a in afimDB.UNITES
     select new EntityIdName { entityId = (int)a.UNIT_ID, entityName = a.UNIT_NAME })
    .AsEnumerable();

var usersWithEntities = (
    from user in imdb.AspNetUsers
    select new
    {
        UserId = user.Id,
        Username = user.UserName,
        Email = user.Email,
        EntityNames = (
            from a in imdb.UserEntities
            join b in imdb.AspNetUsers on a.UserID equals b.Id
            where user.Id == a.UserID
            select new 
            { 
                entity = (
                    from q in entitiesIDs 
                    where q.entityId == 2 
                    select q.entityName)
                    .ToArray()
            })
            .ToList() 
        })
        .AsEnumerable()
        .Select(p => new Users_in_Entities_ViewModel()
        {
            UserId = p.UserId,
            Username = p.Username,
            Email = p.Email,
            Entity = string.Join(",", p.EntityNames)
        });

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Ошибка, которую вы получаете из-за:

IEnumerable<EntityIdName> entitiesIDs = 
    (from a in afimDB.UNITES
     select new EntityIdName { entityId = (int)a.UNIT_ID, entityName = a.UNIT_NAME })
    .AsEnumerable();

AsEnumerable не полностью не выполняет выражение EF.Для этого вам нужно использовать ToList()

IEnumerable<EntityIdName> entitiesIDs = 
    (from a in afimDB.UNITES
     select new EntityIdName { entityId = (int)a.UNIT_ID, entityName = a.UNIT_NAME })
    .ToList();

Теперь у вас будет список POCO EntityIdName, на который можно ссылаться во втором выражении EF.EF выполнит этот второй запрос к контексту imDB, который не может быть включен в выражение из контекста afimDB.

Редактировать: Для демонстрации поведения и настройки.Это просто пример использования двух областей экземпляров DbContext, чтобы продемонстрировать, что запрос из одного контекста не может быть использован в другом.

    using (var context2 = new TestDbContext())
    {
        var ids = context2.Customers
            .Where(x => x.Name == "Fred")
            .Select(x => x.CustomerId)
            .AsEnumerable();
        using (var context = new TestDbContext())
        {
            var customers = context.Customers.Where(x => ids.Contains(x.CustomerId))
                .ToList();
        }
    }

Вышеприведенный сбой с исключением при извлечении клиентов с «Указанное выражение LINQ содержит ссылки на запросы, связанные с различными контекстами.»

    using (var context2 = new TestDbContext())
    {
        var ids = context2.Customers
            .Where(x => x.Name == "Fred")
            .Select(x => x.CustomerId)
            .ToList(); // <- The .ToList you need
        using (var context = new TestDbContext())
        {
            var customers = context.Customers.Where(x => ids.Contains(x.CustomerId))
                .ToList();
        }
    }

Работает, как ожидалось..ToList() выполняет первый запрос к БД в список POCO, который является безопасным в рамках второго запроса..AsEnumerable() нет.

Пожалуйста, оставляйте комментарии конструктивными и, возможно, попробуйте их перед повторным голосованием.

0 голосов
/ 03 октября 2018

Эта часть запроса не имеет никакого смысла:

EntityNames = (
    from a in imdb.UserEntities
    join b in imdb.AspNetUsers on a.UserID equals b.Id
    where user.Id == a.UserID
    select new 
    { 
        entity = (
            from q in entitiesIDs 
            where q.entityId == 2 
            select q.entityName)
            .ToArray()
    })
    .ToList() 
})

Почему вы выбираете данные из таблицы, а затем присоединяетесь к другой, чтобы полностью отбросить их?

Этоможно много упростить:

string unitNames = string.Join(", ", afimDB.UNITES
    .Where(a => a.UNIT_ID == 2)
    .Select(a => a.UNIT_NAME));

var usersWithEntities = (
    from user in imdb.AspNetUsers
    select new Users_in_Entities_ViewModel
    {
        UserId = user.Id,
        Username = user.UserName,
        Email = user.Email,
        Entity = unitNames 
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...