2016-08-26 15 views
1

Entity FrameworkでSqlite.NETを使用して次の結合ステートメントを実行する際に問題が発生しています。Sqlite.NETを使用するEntity Frameworkは、APPLY結合がサポートされていないと文句を言います

私のセットアップは次のとおりです。

.NET Framework v4 Entity Framework v6.0.0.0 SQLite.EF6 v1.0.99.0 SQLite.Linq v1.0.99.0

using (var me = new ChinookContext()) 
{ 
    var screenset = 
     from track in me.Tracks 
     join genre in me.Genres on track.GenreId equals genre.GenreId 
     join artist in me.Artists on track.Album.ArtistId equals artist.ArtistId 
     into artists 
     from artist in artists.DefaultIfEmpty() 
     select new TrackDTO 
     { 
      TrackId = track.TrackId, 
      TrackName = track.Name, 
      GenreId = genre.GenreId, 
      GenreName = genre.Name, 
      ArtistId = artist.ArtistId, 
      ArtistName = artist.Name 
     }; 
     foreach (var track in screenset) 
     { 
      Console.WriteLine(track.TrackId + ", " + track.TrackName + ", " + track.TrackPrice); 
     } 
} 

私は取得していますエラーは次のとおりです。

がサポートされていない結合が適用され

これは、スタックトレースを経由せずに得ることができる内部のものです。

データモデルは、オープンソースのChinookデータベースに基づいています。私が使用しているされて

Chinook Data model

面白いことは、他のSqlite.NETクエリ内のステートメントに参加し、私は前にこれで問題はなかったしています。

何か助けていただければ幸いです。

ありがとうございます。

UPDATE:コマンド定義を準備中

エラーが発生しました:

ここではエラーとスタックトレースがあります。 details.APPLYための内部例外がSystem.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory、DbCommandTree commandTree、DbInterceptionContext interceptionContext、IDbDependencyResolverリゾルバ、BridgeDataReaderFactory bridgeDataReaderFactory、ColumnMapFactory columnMapFactory) でサポートされていないジョイン参照System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContextは文脈、DbQueryCommandTreeツリー)における(DbProviderManifest providerManifest、DbCommandTree commandTree、DbInterceptionContext interceptionContext) で at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContextコンテキスト、DbQueryCommandTreeツリー、Type要素タイプ、1 FUNC System.Data.Entity.Core.Objects.ObjectQuery 1.<>c__DisplayClass3.<GetResults>b__2() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func、IDbExecutionStrategy executionStrategy、System.Data.EntityブールstartLocalTransaction、ブールreleaseConnectionOnSuccess) でMergeOption mergeOption、ブールストリーミング、スパンスパン、IEnumerableを1 compiledQueryParameters, AliasGenerator aliasGenerator) at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable 1 forMergeOption) 。 System.Data.Entity.Internal.LazyEnumerator`1.MoveNextでSystem.Lazy 1.CreateValue() at System.Lazy 1.LazyInitValue() () ATでCore.Objects.ObjectQuery 1.<>c__DisplayClass3.<GetResults>b__1() at System.Data.Entity.Core.Objects.ObjectQuery 1.GetResults(NULL可能1 forMergeOption) at System.Data.Entity.Core.Objects.ObjectQuery 1..GetEnumerator> b__0() D:\ Dev \ Showcase \ ServerSqlLite \ ProgramServerのSqlLiteChinook.Program.Main(String [] args)の行36 の行D:\ Dev \ Showcase \ ServerSqlLite \ Xxx \ Qxx.csのSqlLiteChinook.Qxx.SearchMusic()cs:行28

答えて

1

ラムダ式を使用すると、以下のクエリで必要な結果が得られます。

テーブル間に良好な関係があるので、いつでも子テーブルのすべての行になる.Includeメソッドを使用できます。

以下のクエリでは、親テーブルのアルバムとトラックの間で結合を行っています。アルバムとトラックには、それぞれ子テーブルのアーティストとジャンルが含まれます。

var query3 = db.Albums.Include("Artists").Join(db.Tracks.Include("Genre"), aa => aa.TrackId, tr => tr.ID, (aa, tr) => new 
      { 
       aa, 
       tr 
      }).Select(Finalrow => new TrackDTO 
      { 
       TrackId = Finalrow.tr.ID, 
       TrackName = Finalrow.tr.Name, 
       GenreId = Finalrow.tr.GENREs.Select(g => g.ID).FirstOrDefault(), 
       GenreName = Finalrow.tr.GENREs.Select(g => g.Name).FirstOrDefault(), 
       ArtistId = Finalrow.aa.Artists.Select(a => a.Id).FirstOrDefault(), 
       ArtistName = Finalrow.aa.Artists.Select(a => a.Name).FirstOrDefault() 

      }).OrderBy(t => t.TrackId); 
+0

恩赦私、私が忙しくしているよう返事が遅れについて。私は厄介な 'join'文の代わりにLinqで' .Include'を使って新しいことを学びました!私はあなたのクエリにいくつかの変更を加え、それは今働いています。私も自分の結論に達しました。問題は「トラック」と「アーティスト」の関係です。 'Album'はnullになる可能性がありますので、元のクエリで' track.Album.ArtistId equals artist.ArtistId'が例外をスローします; – superfly71

0

いくつかの変更を加えた後のNagashreeの解決策。ビッグに感謝します。

var query = db.Albums.Include("Artists") 
.Join(db.Tracks.Include("Genre"), aa => aa.AlbumId, tr => tr.AlbumId, 
(aa, tr) => new 
{ 
    aa, 
    tr 
}).Select(Finalrow => new TrackDTO 
{ 
    TrackId = Finalrow.tr.TrackId, 
    TrackName = Finalrow.tr.Name, 
    GenreId = Finalrow.tr.Genre.GenreId, 
    GenreName = Finalrow.tr.Genre.Name, 
    ArtistId = Finalrow.aa.ArtistId, 
    ArtistName = Finalrow.aa.Artist.Name 
}).OrderBy(t => t.TrackId); 

私の元のクエリとの問題あなたはArtistに到達するための方法はありませんのでTrackため、Albumはnullになる可能性があることです。ここでは作業バージョンです。したがって、Linqステートメントtrack.Album.ArtistId equals artist.ArtistIdは例外をスローします。私のような昔ながらのSQLコーダーのために

は、ここで私はjoinを使用して思い付いた作業クエリは次のとおりです。

var screenset = 
from track in me.Tracks 
join genre in me.Genres on track.GenreId equals genre.GenreId 
join album in me.Albums on track.AlbumId equals album.AlbumId 
into albums 
from album in albums.DefaultIfEmpty() 
join artist in me.Artists on album.ArtistId equals artist.ArtistId 
into artists 
from artist in artists.DefaultIfEmpty()    
select new TrackDTO 
{ 
    TrackId = track.TrackId, 
    TrackName = track.Name, 
    GenreId = genre.GenreId, 
    GenreName = genre.Name, 
    ArtistId = artist.ArtistId, 
    ArtistName = artist.Name 
}; 

ここにトリックはAlbumintoalbumsに参加し、それがnullであるかどうかを確認することです。

join album in me.Albums on track.AlbumId equals album.AlbumId 
into albums 
from album in albums.DefaultIfEmpty() 

コーディングハッピー;)

+0

変更されたクエリを投稿していただきありがとうございます!!すべての代替ソリューションを知っておくと良い –

関連する問題