LINQ to Entities无法识别方法,2个存储库

时间:2013-03-22 15:56:14

标签: c# linq entity-framework

我一直在我的代码中得到以下错误,并且无法理解为什么将它转换为查询时遇到问题,这很简单。

我有2个存储库,AlbumAlbumImage,当我获取相册时,我想要一个封面,这是AlbumImages中的子选择。我在这里做错了什么?

  

LINQ to Entities无法识别该方法   'System.Linq.IQueryable`1 [Sogaard.us.Cosplay.Data.AlbumImage] Get()'   方法,并且此方法无法转换为商店表达式。

相册存储库

    public class AlbumRepository : IRepository<Album>
    {
        private CosplayEntities _entities;
        private IRepository<AlbumImage> _imageRepository;

        public AlbumRepository(CosplayEntities entities, IRepository<AlbumImage> imageRepository)
        {
            _entities = entities;
            _imageRepository = imageRepository;
        }

        public IQueryable<Album> Get()
        {
            return (from a in _entities.Albums
                    select new Album()
                        {
                            Id = a.Id,
                            UserId  = a.UserId,
                            Name  = a.Name,
                            Created  = a.Created,
                            LastEdit  = a.LastEdit,
                            Description  = a.Description,
                            Views  = a.Views,
                            Location  = a.Location,
                            Photoshoot  = a.Photoshoot,
                            Cover = (from ai in _imageRepository.Get() where ai.AlbumId == a.Id orderby ai.Cover descending, ai.Id ascending select ai).FirstOrDefault(),
                        });
        }
}

AlbumImage存储库

public class AlbumImageRepository : IRepository<AlbumImage>
{
    private CosplayEntities _entities;

    public AlbumImageRepository(CosplayEntities entities)
{
    _entities = entities;
}

public IQueryable<AlbumImage> Get()
{
    return (from ai in _entities.AlbumImages
            select new AlbumImage()
                {
                    Id = ai.Id,
                    AlbumId = ai.AlbumId,
                    UserId = ai.UserId,
                    Type = ai.Type,
                    Width = ai.Width,
                    Height = ai.Height,
                    Description = ai.Description,
                    Views = ai.Views,
                    Uploadet = ai.Uploadet,
                    LastView = ai.LastView,
                    Thumblink = ai.Thumblink,
                    Imagelink = ai.Imagelink,
                    Cover = ai.Cover
                });
}

这是我在

上收到错误的代码
    _albumImageRepository = new AlbumImageRepository(_entities);
    _albumRepository = new AlbumRepository(_entities, _albumImageRepository);
    _albumImagesTagRepository = new AlbumImagesTagRepository(_entities);
....

    var album = _albumRepository.Get().Where(x => x.Id == image.AlbumId).FirstOrDefault();

更新:我已经在我的IQueryable Get()中评论了Cover = ...,所以它是2个简单选择作为对象。 而且我仍然会遇到像

这样简单的错误
    model.Albums = (from a in _albumRepository.Get()
                    orderby a.Id descending
                    select new AlbumDisplayModel()
                        {
                            Album = a,
                            ImageCount = _albumImageRepository.Get().Where(x => x.AlbumId == a.Id).Count(),
                            User = _userRepository.Get().Where(x => x.Id == a.UserId).FirstOrDefault()
                        })
                        .Skip(AlbumsPrPage * (page - 1))
                        .Take(AlbumsPrPage).ToList();

更新2:如果我将IQueryable Get()重写为以下内容,那么它是否能够完美地运行,那么它应该如何处理?

public IQueryable<Album> Get()
{
    return (from a in _entities.Albums
            select new Album()
                {
                    Id = a.Id,
                    UserId  = a.UserId,
                    Name  = a.Name,
                    Created  = a.Created,
                    LastEdit  = a.LastEdit,
                    Description  = a.Description,
                    Views  = a.Views,
                    Location  = a.Location,
                    Photoshoot  = a.Photoshoot,
                    Cover = (from ai in _entities.AlbumImages where ai.AlbumId == a.Id orderby ai.Cover descending, ai.Id ascending select new AlbumImage()
                    {
                        Id = ai.Id,
                        AlbumId = ai.AlbumId,
                        UserId = ai.UserId,
                        Type = ai.Type,
                        Width = ai.Width,
                        Height = ai.Height,
                        Description = ai.Description,
                        Views = ai.Views,
                        Uploadet = ai.Uploadet,
                        LastView = ai.LastView,
                        Thumblink = ai.Thumblink,
                        Imagelink = ai.Imagelink,
                        Cover = ai.Cover
                    }).FirstOrDefault(),
                });
}

更新3:做了一点测试,问题似乎与Entity框架有关,请看下面的代码,var linqAlbum = testClass.LinqAlbumGet().ToList();执行没有任何问题并返回正确的数据,{ {1}}失败,异常

  

LINQ to Entities无法识别该方法   'System.Linq.IQueryable`1 [RepositoryTest.TestAlbumCover] EEImageGet()'   方法,并且此方法无法转换为商店表达式。

我的测试脚本

var eeAlbum = testClass.EEAlbumGet().ToList();

3 个答案:

答案 0 :(得分:1)

可能是因为您将AlbumAlbumImage包装在新引用中。我会删除它并在查询之后进行投影

答案 1 :(得分:1)

我认为你不能投射到一个实体,并且每个投影都使用另一个IQueryable的结果。如果您用此替换IQueryable<AlbumImage> Get()的内容,则可能有效:

from a in _entities.Albums
join c in _imageRepository.Get() on a.Id equals c.AlbumId into acJoin
from ac in acJoin.DefaultIfEmpty()
select new Album()
{
    Id = a.Id,
    etc..,
    etc..,
    Cover = ac
}

我实际上相当肯定你需要调整这个徒手查询,但实质上它是加入IQueryables,然后将这些结果投射到你的对象中,而不是投射到你的对象然后插入一个可以归结为那些结果。不是我所知道的最好的解释,但只要查看“LINQ Left Join”或“Linq Left Outer Join”,看看我在这里描述的语法。 Example

答案 2 :(得分:1)

您的问题出现在Albir的ItemRepository中。特别是因为_entities不了解_imageRepository类型,所以它不知道如何将该类型转换为适当的TSQL脚本。在尝试从水合对象的范围而不是直接在数据库实例上访问_ImageRepository.Get()之前,可以强制转换_entities.Albums.ToList()以强制IQueryable进入IEnumerable。意识到您将在每个相册的AlbumImage子对象的n + 1数据库请求中看到一个性能命中。

    public IQueryable<Album> Get()
    {
        return (from a in _entities.Albums
                select new Album()
                    {
                        Id = a.Id,
                        UserId  = a.UserId,
                        Name  = a.Name,
                        Created  = a.Created,
                        LastEdit  = a.LastEdit,
                        Description  = a.Description,
                        Views  = a.Views,
                        Location  = a.Location,
                        Photoshoot  = a.Photoshoot,
                        Cover = (from ai in _imageRepository.Get() where ai.AlbumId == a.Id orderby ai.Cover descending, ai.Id ascending select ai).FirstOrDefault(),
                    });
    }

最终,问题在于您尝试使用ActiveRecord模式而不是真正的存储库。需要通过相同的数据库上下文实例获取单个IQueryable中的所有内容,以进行解析和跟踪。