IN и NOT IN с Linq to Entities (EF4.0)

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

Я использую Entity Framework 4.0 для своего приложения.

A Местоположение (например, дом или офис) имеет одно или несколько объектов (например, ванная комната, спальня, стол для снукера и т.д.).

Я хочу отобразить список флажков на странице местоположения с помощью флажка списка объектов, с теми, которые были проверены на наличие в настоящее время местоположения.

Модель My View для объектов выглядит следующим образом:

public class FacilityViewItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Checked { get; set; }
}

Поэтому, когда я передаю модель представления местоположения в пользовательский интерфейс, я хочу передать List<T> объектов, где T имеет тип FacilityViewItem.

Чтобы получить возможности, которые есть у этого местоположения, просто - я делаю запрос, используя Location.Facilities, который возвращает EntityCollection, где T имеет тип Facility. Это потому, что объекты являются навигационным свойством....

var facs = from f in location.Facilities
select new FacilityViewItem()
{
    Id = f.FacilityId,
    Name = f.Name,
    Checked = true
};

Итак, вот где моя проблема - я хочу, чтобы остальные объекты, те, которые не имеют Местоположение.

Я попытался использовать Except() и Any() и Contains(), но я получаю ту же ошибку.

Примеры запросов, которые не работают...

var restOfFacilities = from f in ctx.Facilities
    where !hasFacilities.Contains(f)
    select new FacilityViewItem()
        {
            Id = f.FacilityId,
            Name = f.Name
        };

var restOfFacilities = ctx.Facilities.Except(facilitiesThatLocationHas);

var notFacs = from e in ctx.Facilities
where !hasFacilities.Any(m => m.FacilityId == e.FacilityId)
    select new FacilityViewItem()
        {
            Id = e.FacilityId,
            Name = e.Name
        };

И ошибка, которую я получаю при каждой реализации...

Исправление System.NotSupportedException было необработанным Message = Невозможно создать постоянное значение типа 'Chapter2ConsoleApp.Facility'. В этом контексте поддерживаются только примитивные типы (такие как Int32, String и Guid).

Что я здесь не вижу?

Ответ 1

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

Ошибка в основном говорит: "Я не знаю, как рассчитать, какие элементы не включены, сравнивая сильно типизированные объекты. Дайте мне список интов или некоторых простых типов, и я могу позаботиться об этом".

Итак, сначала вам нужно получить список первичных ключей, а затем использовать это в предложении contains...

//get the primary key ids...
var hasFacilityIds = from f in hasFacilities
    select f.FacilityId;

//now use them in the contains clause...
var restOfFacilities = from f in ctx.Facilities
    where !hasFacilityIds.Contains(f.FacilityId)
        select new FacilityViewItem()
            {
                Id = f.FacilityId,
                Name = f.Name
            };

Ответ 2

Первый запрос кажется прекрасным, но вам нужно сравнить Id s:

var restOfFacilities = from f in ctx.Facilities
                       where !facs.Select(fac => fac.Id).Contains(f.Id)
                       select f;

Ответ 3

Я хочу увидеть, что hasFacilities, так или иначе, как показывает L2E, "В этом контексте поддерживаются только примитивные типы (такие как Int32, String и Guid)", поэтому я предполагаю, что вы должны сначала извлечь данные и вставить их в коллекция FacilityViewItem.

var restOfFacilities = ctx
    .Facilities
    .Where(f => !hasFacilities.Contains(f))
    .Select(f => new { f.FacilityId, f.Name })
    .ToList()
    .Select(f => new FacilityViewItem {
        Id = f.FacilityId,
        Name = f.Name
    });

var notFacs = ctx
    .Facilities
    .Where(e => !hasFacilities.Any(m => m.FacilityId == e.FacilityId))
    .Select(e => new { e.FacilityId, e.Name })
    .ToList()
    .Select(e => new FacilityViewItem {
        Id = e.FacilityId,
        Name = e.Name
    });

надеюсь, что это поможет