Возврат коллекции объектов, где свойство объектов соответствует любому свойству из другой коллекции объектов с использованием LINQ-to-Entities

Я искал весь день и не могу найти решение этой проблемы...

у меня есть EntityCollection из Communication объекты, каждый из которых имеет экземпляр Intention Объект (один к одному).

у меня тоже есть User объект, который имеет много экземпляров UserLocationEntityObjects (один ко многим)

  • Intention объекты имеют свойство UID,
  • UserLocation объекты имеют свойство LID,

  • Я хочу написать выражение LINQ, которое возвращает все Communication объекты, где UID собственность Intention экземпляр, связанный с Communication объект равен ЛЮБОМУ LID свойство ЛЮБОГО экземпляра UserLocation экземпляр для User объект.

Я пробовал это

return _context.Communications.Where
(u => u.Intention.UID.Equals
(user.UserLocations.Select
(p => p.LID)));

и это

return _context.Communications.Where
(u => user.UserLocations.Any
(x => x.LID.Equals
(u.Intention.UID)));

и это

var thislist = from Intentions in _context.Intentions
                           join UserLocations in user.UserLocations
                           on Intentions.UID equals UserLocations.LID
                           select Intentions.UID;
            return _context.Communications.Where(u => u.Intention.Equals(thislist.Any()));

и это

var lidlist = user.UserLocations.Select(x => x.LID);
return _context.Communications.Where(x=> lidlist.Contains(x.Intention.UID)).ToList();

(это дает мне ошибку в выражении Contains, в котором говорится: "Делегат System.Func<Communication,int,bool> не принимает 1 аргумент ", не знаю, как исправить)

Наряду со всеми этими вариациями я также:

  • изменил мой метод, чтобы вернуться IQueryable<Communication> и также пытался List<Communication> при добавлении ToList() на мои вопросы.

Ничего не работает Независимо от того, что я пытаюсь, я всегда получаю это исключение

NotSupportedException не было обработано кодом пользователя

Невозможно создать постоянное значение типа "PreparisCore.BusinessEntities.UserLocation". В этом контексте поддерживаются только примитивные типы (такие как Int32, String и Guid).

Что я делаю неправильно??

2 ответа

Решение

Учитывая этот код:

namespace CollectionsWithIntentions
{
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;

    internal class Program
    {
        #region Methods

        private static void Main(string[] args)
        {
            var communications = new[]
                {
                    new Communication { Intention = new Intention { UID = 1 } },
                    new Communication { Intention = new Intention { UID = 2 } },
                    new Communication { Intention = new Intention { UID = 3 } },
                    new Communication { Intention = new Intention { UID = 4 } },
                };
            var users = new[]
                {
                    new User { UserLocations = new List<UserLocation>(new[] { new UserLocation { LID = 2 },new UserLocation{LID=5}  }) },
                    new User { UserLocations = new List<UserLocation>(new[] { new UserLocation { LID = 3 } }) }
                };

            IEnumerable<Communication> res =
                communications.Where(w => users.Any(a => a.UserLocations.Any(b=>b.LID == w.Intention.UID)));
            foreach (Communication communication in res)
            {
                Trace.WriteLine(communication);
            }
        }

        #endregion
    }

    internal class Communication
    {
        #region Public Properties

        public Intention Intention { get; set; }

        #endregion

        #region Public Methods and Operators

        public override string ToString()
        {
            return string.Concat("Communication-> Intention:", this.Intention.UID);
        }

        #endregion
    }

    internal class Intention
    {
        #region Public Properties

        public int UID { get; set; }

        #endregion
    }

    internal class User
    {
        #region Public Properties

        public List<UserLocation> UserLocations { get; set; }

        #endregion
    }

    internal class UserLocation
    {
        #region Public Properties

        public int LID { get; set; }

        #endregion
    }
}

Я получаю этот результат:

Communication-> Intention:2
Communication-> Intention:3

Я что-то пропустил?

Из последних двух ошибок компилятора вы связали в одном из ваших комментариев...

... я бы пришел к выводу, что Intention.UID обнуляемый тип int? и не ненулевой int как вы сказали в комментариях. Это действительно не компилируется. Попробуйте изменить свой последний запрос на:

var lidlist = user.UserLocations.Select(x => x.LID);
return _context.Communications
    .Where(x => x.Intention.UID.HasValue
             && lidlist.Contains(x.Intention.UID.Value))
    .ToList();

Три других запроса не работают, потому что user.UserLocations является коллекцией непримитивного пользовательского типа в памяти (для генерируемого SQL-запроса это "постоянное" значение), и EF не поддерживает создание SQL-запроса с таким постоянным пользовательским типом.

Другие вопросы по тегам