无法创建类型(类型)的常量值在此上下文中仅支持基本类型(例如Int32,String和Guid')

时间:2011-08-28 12:10:14

标签: linq entity-framework linq-to-entities many-to-many

我已经阅读了所有内容:

并搜索了一下,但仍然没有解决方案。我已经看到这种情况发生在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对象,如果有帮助的话。我不确定错误的真正原因,我在脑海中没有任何其他查询的想法。我认为方法名称非常自我解释:我正试图在给定的专辑中获取照片。将相册条目加载到内存中不是解决方案,查询应该在数据库上运行,而不是在内存上运行。我需要解释此异常,为什么它出现在这里,以及如何让我的查询工作。

4 个答案:

答案 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,它有效。可能会有所帮助。