Как использовать «Содержит» с Guid?

Я пытаюсь получить все сущности из контекста, находящегося в коллекции. Пока это работает так:

Ticket ticket = context.Tickets.Where(p => p.TicketId == ticketId);
ticket.Tasks.Where(p => !message.Tasks.Select(t => t.Id).Contains(p.Id));

это заканчивается исключением таким образом

context.Tasks.Where(p => message.Tasks.Select(t => t.Id).Contains(p.Id));

Обратите внимание, что Id относится к типу Guid

Мой вопрос: как мне написать второй запрос, чтобы получить все задачи из контекста, которые находятся в коллекции message.Tasks?

Редактировать

Исключение NotSupportedException

Не удалось создать постоянное значение типа DataObjects.KeyValueDataObject`2[[System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Культура = нейтральная, PublicKeyToken = b77a5c561934e089]]'. В этом контексте поддерживаются только примитивные типы или типы перечисления.

И класс

public class KeyValueDataObject 
{ 
    public TKey Id { get; set; } 
    public TValue Name { get; set; } 
}

Реализовано как KeyValueDataObject<Guid,String>


person JJR    schedule 19.05.2014    source источник
comment
Что является исключением?   -  person DavidG    schedule 20.05.2014


Ответы (3)


Проблема в том, что Linq-to-Entities должен преобразовать ваш список в постоянное выражение, чтобы превратить ваш Contains в оператор IN, который может не работать с GUID.

Попробуйте сначала извлечь запросы в «постоянный» список:

var lookup = message.Tasks.Select(t => t.Id).ToList();
context.Tasks.Where(p => lookup.Contains(p.Id));
person D Stanley    schedule 19.05.2014
comment
Вот и все! Спасибо! - person JJR; 20.05.2014

Попробуй это:

var taskIds = message.Tasks.Select(t => t.Id).ToArray();
context.Tasks.Where(p => taskIds.Any(t => t.Id == p.Id));
person SoftwareFactor    schedule 19.05.2014
comment
Нет :( все то же исключение - person JJR; 20.05.2014
comment
Я не знал, что Tasks — это KeyValuePair. Обновил мой ответ сейчас. - person SoftwareFactor; 20.05.2014
comment
Ты прав! Я выбрал голодный как правильный. в любом случае, ты получил мой +1 - person JJR; 20.05.2014

Попробуйте с этим:

var tasks = context.Tasks.ToList().Where(p => message.Tasks.ToList().Any(t => t.Id.Contains(p.Id)));

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

код ОТРЕДАКТИРОВАН

person Oscar Bralo    schedule 19.05.2014
comment
Спасибо за ответ, но он заканчивается на Cannot convert lambda expression to delegate type 'System.Func<KeyValueDataObject<System.Guid,string>,bool>' because some of the return types in the block are not implicitly convertible to the delegate return type Я думаю, это из-за общего типа данных? - person JJR; 20.05.2014
comment
Да, может быть. Почему бы вам не попробовать преобразовать идентификаторы в строку вместо того, чтобы пытаться работать с самими справочными данными? Что-то вроде KeyValueDataObject‹String,String› - person Oscar Bralo; 20.05.2014
comment
Хорошо, что заканчивается на Instance argument: cannot convert from 'System.Collections.Generic.IEnumerable<string>' to 'System.Linq.IQueryable<System.Guid>' - person JJR; 20.05.2014
comment
мм, возможно, с отредактированным кодом, который я написал. Преобразование ToList обеих частей, но .. Я не уверен, только догадываюсь и пытаюсь помочь вам на этом этапе. - person Oscar Bralo; 20.05.2014
comment
Ты прав! Я выбрал голодный как правильный. в любом случае, ты получил мой +1 - person JJR; 20.05.2014
comment
Спасибо, бро! ;) Рад помочь или хотя бы попробовать! - person Oscar Bralo; 20.05.2014