Невозможно создать постоянное значение типа (типа) В этом контексте поддерживаются только примитивные типы (такие как Int32, String и Guid)
Я прочитал ВСЕ:
и искал немного больше, но все равно никакого решения. Я видел, что это происходит на EF 3.5, а в 4.0 метод Contains
должен поддерживаться, но я в EF 4, но я получаю эту ошибку. У меня есть фотогалерея, где альбомы могут иметь любое количество разных фотографий, и каждая фотография может принадлежать любому количеству альбомов. Так что это отношения "многие ко многим".
У меня есть свойство VisibleObjects
, которое используется примерно 100 другими методами, которые работают хорошо, но я все равно вставляю его: (я определенно уверен, что проблема не вызвана что-то здесь)
static IQueryable<GlobalObject> VisibleObjects
{
get
{
return from obj in db.GlobalObjectSet where obj.IsVisible && !obj.SiteUser.IsDeactivated orderby obj.ID descending select obj;
}
}
Я пробовал несколько разных запросов:
У меня есть свойство VisiblePhotos
:
Это не работает:
static IQueryable<Photo> VisiblePhotos(this Album a)
{
return from p in VisibleObjects.OfType<Photo>() where a.Photos.Contains(p) select p;
}
Изменено:
static IQueryable<Photo> VisiblePhotos(this Album a)
{
return from p in VisibleObjects.OfType<Photo>() where a.Photos.Any(other => p.ID == other.ID) select p;
}
Все еще не работает.
Вот вызывающий метод:
public static List<Photo> GetLatestPhotosByAlbum(Album alb, int count = 3)
{
lock (sync)
{
return alb.VisiblePhotos().OrderByDescending(p => p.ID).Take(count).ToList();
}
}
Не работает, изменено на это:
public static List<Photo> GetLatestPhotosByAlbum(Album alb, int count = 3)
{
lock (sync)
{
return (from p in VisibleObjects.OfType<Photo>()
where alb.Photos.Any(ph => ph.ID == ph.ID)
select p).ToList();
}
}
Все еще не работает. Жалуется на невозможность создания константы моего типа объекта фото, который является объектом Entity с свойством ID, если это помогает. Я не уверен в реальной причине ошибки, и у меня нет других идей в моем сознании. Я думаю, что имя метода довольно понятно: я пытаюсь получить фотографии в данном альбоме. Загрузка записей альбомов в память не является решением, запрос должен выполняться в базе данных, а не в памяти. Мне нужно объяснение этого исключения, почему это происходит здесь, и как я могу заставить свой запрос работать.
Ответы
Ответ 1
Это не сработает, потому что вы хотите использовать локальный альбом в запросе linq-to-entities. Вы должны либо использовать свойство навигации на p, чтобы получить его альбом:
var query = from p in VisibleObjects.OfType<Photo>()
where p.Album.Id == alb.Id
select p;
или вы должны создать сложный запрос с некоторым соединением между фотографиями и альбомами. Вы не можете передать локальный объект и любое его отношение к запросу. Можно передавать только простые свойства.
Ответ 2
Я думаю, что EF пытается преобразовать where a.Photos.Contains(p)
в SQL как WHERE p IN (a.Photos)
, но не знает, как выразить a.Photos
в SQL. SQL, который вы хотите, вероятно, выглядит как WHERE p.Id IN (1, 2, 3)
, поэтому вы можете попробовать сделать это на С#:
static IQueryable<Photo> VisiblePhotos(this Album a)
{
var photoIds = a.Photos.Select(p => p.Id).ToArray();
return from p in VisibleObjects.OfType<Photo>() where photoIds.Contains(p.Id) select p;
}
Ответ 3
Я попробовал другой способ, и это сработало:
static IQueryable<Photo> VisiblePhotos(this Album a)
{
return from p in VisibleObjects.OfType<Photo>()
where p.Albums.Any(alb => a.ID == alb.ID)
select p;
}
Довольно странно видеть, что это работает, а другое - нет. Но мне все еще интересно, почему Contains
не работает.
Ответ 4
У меня возникла аналогичная проблема, и вместо IQueryable я попытался использовать List, и он сработал. Может быть, поможет.