我已经阅读了所有内容:
Unable to create a constant value of type 'System.Object' in Entity Framework
Entity Framework - "Unable to create a constant value of type 'Closure type'..." error
Entity Framework - Union causes "Unable to create a constant value of type.."
Only primitive types ('such as Int32, String, and Guid') are supported in this context
并搜索了一下,但仍然没有解决方案。我已经看到这种情况发生在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();
}
}
仍然无法正常工作。抱怨无法创建我的Photo对象类型的常量,这是一个具有ID属性的Entity对象,如果有帮助的话。我不确定错误的真正原因,我在脑海中没有任何其他查询的想法。我认为方法名称非常自我解释:我正试图在给定的专辑中获取照片。将相册条目加载到内存中不是解决方案,查询应该在数据库上运行,而不是在内存上运行。我需要解释此异常,为什么它出现在这里,以及如何让我的查询工作。
答案 0 :(得分:12)
它不起作用,因为您想在linq-to-entities查询中使用本地相册。您必须使用p上的导航属性来获取其相册:
var query = from p in VisibleObjects.OfType<Photo>()
where p.Album.Id == alb.Id
select p;
或者您必须使用照片和相册之间的某些连接来构建复杂查询。您不能将本地对象及其任何关系传递给查询。只能传递简单的属性。
答案 1 :(得分:5)
我认为EF正试图将where a.Photos.Contains(p)
转换为像WHERE p IN (a.Photos)
这样的SQL,但它不知道如何在SQL中表达a.Photos
。您想要的SQL可能看起来像WHERE p.Id IN (1, 2, 3)
,因此您可以尝试在C#中执行此操作:
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;
}
答案 2 :(得分:0)
我尝试了另一种方式并且有效:
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
无效。
答案 3 :(得分:0)
我遇到了类似的问题,而不是IQueryable,我尝试使用List,它有效。可能会有所帮助。