简体   繁体   中英

Linq to query with multiple row subquery (without join)

I'd like to make a query with multiple row subquery as we do in MySql but I want to do it without join , so my sql query is:

select * from html_files_tab where html_files_tab.encoded_id in
(select html_src_files_relationsip_tab.file_fk from html_src_files_relationsip_tab where html_src_files_relationsip_tab.src_fk == '1' );

I tried:

var fileBeans = ( from srcFileTab in conn.Table<FileBean>() where 
                  srcFileTab.fileId in ( from srcFileRelationSipTab in 
                  conn.Table<HtmlSrcFileRelationship>() where 
                  srcFileRelationSipTab.srcFk == encodedSrcId select               
                  srcFileRelationSipTab.fileFk ) select srcFileTab ).ToList();

But I get some errors, is there a way to do it without Join?

ps using join method:

   var fileBeans = ( from fileTab in conn.Table<FileBean>()
                                  join relationTab in conn.Table<HtmlSrcFileRelationship>()
                                  on fileTab.fileId equals relationTab.fileFk
                                  where relationTab.srcFk == encodedSrcId && relationTab.srcFk == encodedSrcId
                                  select fileTab ).ToList();

Using join I get an exception:

Exception thrown: 'System.NotSupportedException' in SQLite.Net.dll

full stack trace:

   at SQLite.Net.TableQuery`1.GenerateCommand(String selectionList)
   at SQLite.Net.TableQuery`1.GetEnumerator()
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at HiTech.DataBase.selectFileBeansBySrc(String encodedSrcId)

Instead of trying to recreate SQL in LinQ you can use the LinQ option of nested iterations which is pretty much the same as a subquery.

var tabs = (from srcFileTab in conn.Table<FileBean>()
            from srcFileRelationSipTab in conn.Table<HtmlSrcFileRelationship>() 
            where srcFileRelationSipTab.srcFk == encodedSrcId 
               && srcFileTab.fileId == srcFileRelationSipTab.fileFk
            select srcFileTab ).ToList();

is there a way to do it without Join?

You could use Any extension and do this.

conn.Table<FileBean>()
    .Select(x=>  conn.Table<HtmlSrcFileRelationship>()
                     .Any(r=> r.srcFk == encodedSrcId  && r.srcFk  == x.encoded_id)) 
                     // not sure it is encoded_id or encodedSrcId in above statement. Update accordingly.  
    .ToList();

Can't you do it in two separate queries?

var fileRel = (from srcFileRelationSipTab in 
              conn.Table<HtmlSrcFileRelationship>() where 
              srcFileRelationSipTab.srcFk == encodedSrcId 
              select srcFileRelationSipTab.fileFk).ToList();

var fileBeans = ( from srcFileTab in conn.Table<FileBean>() where 
              srcFileTab.fileId in fileRel 
              select srcFileTab ).ToList();

The direct LINQ equivalent of SQL IN operator is Contains method:

var fileBeans = 
    (from srcFileTab in conn.Table<FileBean>()
     where (from srcFileRelationSipTab in conn.Table<HtmlSrcFileRelationship>()
            where srcFileRelationSipTab.srcFk == encodedSrcId
            select srcFileRelationSipTab.fileFk).Contains(srcFileTab.fileId)
     select srcFileTab).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM