我在使用Sqlite.NET和Entity Framework执行以下连接语句时遇到问题。
我的设置是:
.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);
}
}
我得到的错误是:
不支持APPLY联接
这就像我可以在不经过堆栈跟踪的情况下获得内部。
数据模型基于开源的Chinook数据库。
有趣的是我在其他Sqlite.NET查询中使用了join语句,之前我没有遇到任何问题。
感谢任何帮助。
提前致谢。
更新
这是错误和堆栈跟踪:
准备命令定义时发生错误。有关详细信息,请参阅内部异常。不支持APPLY连接 在System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory,DbCommandTree commandTree,DbInterceptionContext interceptionContext,IDbDependencyResolver resolver,BridgeDataReaderFactory bridgeDataReaderFactory,ColumnMapFactory columnMapFactory) 在System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest,DbCommandTree commandTree,DbInterceptionContext interceptionContext) 在System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context,DbQueryCommandTree tree) 在System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context,DbQueryCommandTree tree,Type elementType,MergeOption mergeOption,Boolean streaming,Span span,IEnumerable
1 compiledQueryParameters, AliasGenerator aliasGenerator) at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable
1 forMergeOption) at System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClass3.<GetResults>b__2() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func
1 func,IDbExecutionStrategy executionStrategy,Boolean startLocalTransaction,Boolean releaseConnectionOnSuccess) at System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClass3.<GetResults>b__1() at System.Data.Entity.Core.Objects.ObjectQuery
1.GetResults(Nullable1 forMergeOption) at System.Data.Entity.Core.Objects.ObjectQuery
1..GetEnumerator&gt; b__0() 在System.Lazy1.CreateValue() at System.Lazy
1.LazyInitValue() 在System.Data.Entity.Internal.LazyEnumerator`1.MoveNext() 在D:\ Dev \ Showcase \ ServerSqlLite \ Xxx \ Qxx.cs中的SqlLiteChinook.Qxx.SearchMusic():第36行 在D:\ Dev \ Showcase \ ServerSqlLite \ ProgramServer.cs中的SqlLiteChinook.Program.Main(String [] args):第28行
答案 0 :(得分:1)
使用Lambda表达式,下面的查询将有助于提供所需的结果。
由于表之间存在良好的关系,因此您始终可以使用.Include方法,该方法将包含子表的所有行。
在下面的查询中,我完成了父表album和track之间的连接。专辑和曲目将分别包括它的儿童表艺术家和流派。
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);
答案 1 :(得分:0)
A1 = foreach A generate id,name;
B1 = foreach B generate id,name;
M2 = union A1,B1;
M2 = distinct M2;
M2A = JOIN M2 by id left outer,A by id;
M2AB = JOIN M2A by M2::id left outer, B by id;
Res = foreach M2AB generate M2A::M2::id as id,M2A::M2::name as name,M2A::A::age as age,B::grades as grades;
我的原始查询存在的问题是,对于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);
,Track
可能为空,因此您无法访问Album
。因此,Linq语句Artist
将抛出异常。
对于像我这样的老式SQL编码器,这是我使用track.Album.ArtistId equals artist.ArtistId
提出的工作查询:
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
};
Album
into
并检查它是否为空。
albums
快乐的编码;)