-1

コードで以下のエラーが発生し続けますが、クエリへの変換に問題がある理由を理解できません。これは非常に単純です。

私は 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:少しテストを行いましたが、問題はエンティティ フレームワークにあるようです。次のコードを参照してください。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

あなたの問題は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 に答える
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
}

実際には、このフリーハンド クエリを調整する必要があることはかなり確信していますが、基本的には、オブジェクトに投影してから IQueryable をそれらの結果に挿入するのではなく、IQueryables を結合してから、それらの結果をオブジェクトに投影します私が知っている最良の説明ではありませんが、「LINQ Left Join」または「Linq Left Outer Join」を調べて、ここで説明している構文を確認してください。

于 2013-03-22T16:46:03.017 に答える
1

新しい参照でAlbumandをラップしている可能性があります。AlbumImage私はそれを削除し、クエリのに投影を行います。

于 2013-03-22T15:58:22.693 に答える