"Apply joins is not supported" in SQLite Query

时间:2017-10-12 09:50:49

标签: c# sql-server sqlite select include

I'm trying convert my application with MS SQL Server 2014 database to SQlite. This query works well on SQL Server, but with SQLite, i encounter "APPLY JOINS is not supported" error.

this error exist only with *select ( & include) query.

Query:

        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;
    }

If i comment this line: .Include(s => s.Cdts.Select(r => r.CdtFiches))

        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;
    }

It works well.

If i comment another line: .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;
    }

it works well too.

Are there any specific rules to sqlite select query?

1 个答案:

答案 0 :(得分:0)

我知道这是一个旧线程,但我今天遇到了它,所以这是我给任何未来读者的两分钱

这个有点非常规的错误要么是由于 SQLite 数据库的工作方式,要么是 EF 的 SQLite 提供程序的编写方式。

在这两种情况下,为了简单地“使查询工作”而修复此问题的希望不大。

但是,我发现了一种解决方法来规避此问题。虽然它可能没有利用 EF 的强大功能,但它可以完成工作。

问题的核心

主要问题是此 LINQ 查询试图在同一个一对多表(在您的情况下为 Include)上Cdts 两个一对多导航属性。

在“多层次”上尝试 Include 时,在纯 LINQ 中使用 Include 执行此操作的一种方法是放入 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))

在这里,我想您想同时包含 CdtFichesSessions,它们是 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;
}

这很糟糕。但它有效。