我正在尝试将带有MS SQL Server 2014数据库的应用程序转换为SQlite。这个查询在SQL Server上运行良好,但在使用SQLite时,我遇到了"不支持APPLY JOINS"错误。
此错误仅存在于*select(&include)查询中。
查询:
public static IList<Projet> GetListByClientWithDetails(long IdClient)
{
IList<Projet> resultList = null;
using (FITSEntities db_context = new FITSEntities())
{
resultList = db_context.Projet.Where(s => s.IdClient == IdClient)
.Include(s => s.Cdts.Select(r => r.CdtFiches))
.Include(s => s.Cdts.Select(r => r.Sessions))
.Include(s => s.Fiches.Select(r => r.FicheVersions))
.ToList();
}
return resultList;
}
如果我评论这一行:.Include(s=>s.Cdts.Select(r=>r.CdtRiches))
public static IList<Projet> GetListByClientWithDetails(long IdClient)
{
IList<Projet> resultList = null;
using (FITSEntities db_context = new FITSEntities())
{
resultList = db_context.Projet.Where(s => s.IdClient == IdClient)
// .Include(s => s.Cdts.Select(r => r.CdtFiches))
.Include(s => s.Cdts.Select(r => r.Sessions))
.Include(s => s.Fiches.Select(r => r.FicheVersions))
.ToList();
}
return resultList;
}
它运行良好。
如果我评论另一行:.Include(s=>s.Cdts.Select(r=>r.Sessions))
public static IList<Projet> GetListByClientWithDetails(long IdClient)
{
IList<Projet> resultList = null;
using (FITSEntities db_context = new FITSEntities())
{
resultList = db_context.Projet.Where(s => s.IdClient == IdClient)
.Include(s => s.Cdts.Select(r => r.CdtFiches))
// .Include(s => s.Cdts.Select(r => r.Sessions))
.Include(s => s.Fiches.Select(r => r.FicheVersions))
.ToList();
}
return resultList;
}
它也很好用。
sqlite选择查询有什么特定的规则吗?
我知道这是一个旧线程,但我今天就遇到了,所以这是我给未来读者的两分钱
这个有点非常规的错误要么是由于SQLite数据库的工作方式,要么是由于EF的SQLite提供程序的编写方式。
在任何一种情况下,为了简单地";使查询工作";。
然而,我找到了一个变通方法来规避这个问题。虽然它可能没有利用EF的力量,但它完成了任务。
问题的核心
主要问题是,此LINQ查询试图Include
同一个一对多表(在您的情况下为Cdts
)上的两个一对很多导航属性。
当尝试在"多个级别"上Include
时,在使用Include
的纯LINQ中执行此操作的一种方法是放入Select
resultList = db_context.Projet.Where(s => s.IdClient == IdClient)
.Include(s => s.Cdts.Select(r => r.CdtFiches))
.Include(s => s.Cdts.Select(r => r.Sessions))
在这里,我想您希望同时包括CdtFiches
和Sessions
,它们是Cdt
表上的一对多关系。然而,SQLite不喜欢这样(我不知道为什么,因为SQLServer对此很满意)。
您需要做的是手动Select
根实体,并使用ToList
强制获取相关实体。这实现了与Include
完全相同的结果(尽管我怀疑后者更有效)。
在您的情况下
resultList = db_context.Projet.Where(s => s.IdClient == IdClient)
.Select(_toDeepProjet)
.ToList()
private Projet _toDeepProjet(Projet p)
{
p.Cdts = p.Cdts.Select(_toDeepCdts).ToList();
return p;
}
private Cdts _toDeepCdts(Cdts c)
{
// Force the fetching of entities
// It is equivalent to writing two Includes in your original query
c.CdtFiches = c.CdtFiches.ToList();
c.Sessions = c.Sessions.ToList();
return c;
}
这太离谱了。但它是有效的。