-1

我的代码不断收到以下错误,并且无法理解为什么将其转换为查询时出现问题,这很简单。

我有 2 个存储库,Album并且AlbumImage,当我获取专辑时,我是否想要封面,这是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(),
                        });
        }
}

专辑图片库

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:做了一点测试,问题似乎与实体框架有关,请查看以下代码,var linqAlbum = testClass.LinqAlbumGet().ToList();执行没有任何问题并返回正确的数据,var eeAlbum = testClass.EEAlbumGet().ToList();失败并出现异常

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

我的测试脚本

class Program
{
    static void Main(string[] args)
    {
        var linq = new LinqDataContext();
        var ee = new NewCosplayEntities();

        var testClass = new Test(linq, ee);

        var linqAlbum = testClass.LinqAlbumGet().ToList();
        var eeAlbum = testClass.EEAlbumGet().ToList();
    }
}


    public class Test
    {
        public NewCosplayEntities ee { get; set; }
        public LinqDataContext linq { get; set; }

        public Test(LinqDataContext linq, NewCosplayEntities ee)
        {
            this.linq = linq;
            this.ee = ee;
        }

        public IQueryable<TestAlbum> LinqAlbumGet()
        {
            return from a in linq.Albums
                   select new TestAlbum
                   {
                       Id = a.Id,
                       Name = a.Name,
                       Cover = (from i in LinqImageGet() where i.AlbumId == a.Id select i).FirstOrDefault()
                   };
        }

        public IQueryable<TestAlbumCover> LinqImageGet()
        {
            return from i in linq.AlbumImages
                   select new TestAlbumCover()
                   {
                       Id = i.Id,
                       AlbumId = i.AlbumId
                   };
        }

        public IQueryable<TestAlbum> EEAlbumGet()
        {
            return from a in ee.Albums
                   select new TestAlbum
                   {
                       Id = a.Id,
                       Name = a.Name,
                       Cover = (from i in EEImageGet() where i.AlbumId == a.Id select i).FirstOrDefault()
                   };
        }

        public IQueryable<TestAlbumCover> EEImageGet()
        {
            return from i in ee.AlbumImages
                   select new TestAlbumCover()
                   {
                       Id = i.Id,
                       AlbumId = i.AlbumId
                   };
        } 
    }

    public class TestAlbum
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public TestAlbumCover Cover { get; set; }
    }

    public class TestAlbumCover
    {
        public int Id { get; set; }

        public int AlbumId { get; set; }
    }
4

3 回答 3

1

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

于 2013-03-22T15:58:22.693 回答
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,然后将这些结果投影到您的对象中,而不是投影到您的对象然后将 IQueryable 插入到这些结果中。这不是我所知道的最佳解释,但只需查找“LINQ Left Join”或“Linq Left Outer Join”即可查看我在此处描述的语法。例子

于 2013-03-22T16:46:03.017 回答
1

您的问题出现在 Albumn 的 ItemRepository 中。特别是因为 _entities 不知道 _imageRepository 类型,所以它不知道如何将该类型转换为适当的 TSQL 脚本。_entities.Albums.ToList()在尝试从水合对象的范围而不是直接在数据库实例上访问 _ImageRepository.Get() 之前,您可以强制将 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 中的所有内容都需要通过相同的数据库上下文实例获取,以进行解析和跟踪。

于 2013-03-22T19:03:56.357 回答