C# LINQ to实体无法识别该方法,2个存储库

C# LINQ to实体无法识别该方法,2个存储库,c#,linq,entity-framework,C#,Linq,Entity Framework,我一直在我的代码中发现下面的错误,不明白为什么它在将其转换为查询时遇到问题,它非常简单 我有两个存储库,Album和AlbumImage,当我取出一张专辑时,我是否需要封面,这是AlbumImages中的一个子选择。我做错了什么 LINQ to实体无法识别该方法 'System.Linq.IQueryable'1[Sogaard.us.Cosplay.Data.AlbumImage]Get()' 方法,而此方法无法转换为存储表达式 相册存储库 public class AlbumRepo

我一直在我的代码中发现下面的错误,不明白为什么它在将其转换为查询时遇到问题,它非常简单

我有两个存储库,
Album
AlbumImage
,当我取出一张专辑时,我是否需要封面,这是
AlbumImages
中的一个子选择。我做错了什么

LINQ to实体无法识别该方法 '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
                });
}
更新:我已经对封面发表了评论=。。。在我的IQueryable Get()中,它是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(),
                });
}

可能是因为您正在新引用中包装
相册
相册图像
。我会在您的查询之后删除它并进行投影。

我不认为您可以投影到一个实体中,并让每个投影使用另一个IQueryable的结果。如果您替换了
IQueryable

的内容,您的问题将出现在Albumn的ItemRepository中。特别是因为_实体不知道_imageRepository类型,所以它不知道如何将该类型转换为适当的TSQL脚本。您可以强制转换
\u entities.Albums.ToList()
,在尝试从水合对象的作用域而不是直接在数据库实例上访问_ImageRepository.Get()之前,将IQueryable强制转换为IEnumerable。请注意,接下来您将看到对每个相册的AlbumImage子对象的n+1数据库请求的perf hit

    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 IQueryable Get()
{
返回(从相册中的
选择新相册()
{
Id=a.Id,
UserId=a.UserId,
Name=a.Name,
创造的,创造的,
LastEdit=a.LastEdit,
描述,
视图=a.视图,
位置=a.位置,
照相,
Cover=(来自_imageRepository.Get()中的ai,其中ai.AlbumId==a.Id orderby ai.Cover descending,ai.Id descending选择ai.FirstOrDefault(),
});
}

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

我不明白你的意思?@DoomStone不执行
。选择
Get
中的
部分。这将在使用时击败整个idearrepositories@DanielA.White不会
Get()
不起作用,因为?我刚刚更新了我的问题,Linq是否无法处理select中的新选择?我知道Linq2sql可以轻松地解决这个问题?EF故意禁止许多允许实体和对象查询之间进行模糊混合的查询。如果这在LINQtoSQL中起作用,那么很可能会导致一个n+1查询,其中每个子查询将单独执行。您当然可以选择数据的子集,但您需要这样做,即它知道如何提前获取所有查询信息。在您对问题的更新中,新查询仍会重复EF有问题的部分。我敢打赌,如果您将in-albumRepository.Get()
中的
替换为in-albumRepository.Get().ToList()
中的
,它一定会工作。注意:作为最终解决方案,这不是你应该做的,但希望能澄清问题所在。区别在于a)他们使用不同的上下文。B) 通过EF不知道的方法引用。无论哪种方式,首选的语法都是使用join。这里的子选择非常笨拙,表达的连接有点混乱。我明白了,但是当我使用Linq2Sql进行操作时,它是否工作正常,并且它自动检测该关系并将其转换为左连接。实体框架还没有在Linq2Sql中实现这些功能吗?我很惊讶地听说L2S可以与不同的存储库和上下文一起工作。您确定没有访问a.AlbumImage而不是_imageRepository.Get吗?L2S和EF确实有一些不同的语义,但我不会说它不够高级。您可以在OPIn中看到我的示例。在该示例中,您使用的是相同的上下文,但投影到本地(DTO)对象类型。可能L2S可以提升本地类型,而EF要求本地类型为EF映射模型。您可以通过替换EEImageGet以返回AlbumImage而不是TestAlbumCover对象来测试这一点。话虽如此,您仍然会在具有多个上下文的原始查询中遇到问题。
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; }
    }
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
}
    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(),
                    });
    }