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

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

10 голосов
/ 23 марта 2011

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

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

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

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

Моя модель представления для объектов выглядит следующим образом ...

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).

Что я здесь пропускаю?

Ответы [ 3 ]

19 голосов
/ 23 марта 2011

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

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

Итак, сначала вам нужно получить список первичных ключей, а затем использовать его в предложении 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
            };
7 голосов
/ 23 марта 2011

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

var restOfFacilities = from f in ctx.Facilities
                       where !facs.Select(fac => fac.Id).Contains(f.Id)
                       select f;
1 голос
/ 23 марта 2011

Я хочу посмотреть, что такое hasFacabilities, как показывает 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
    });

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

...