我一直在我的代码中得到以下错误,并且无法理解为什么将它转换为查询时遇到问题,这很简单。
我有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(),
});
}
}
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();
答案 0 :(得分:1)
可能是因为您将Album
和AlbumImage
包装在新引用中。我会删除它并在查询之后进行投影。
答案 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中的所有内容,以进行解析和跟踪。