简体   繁体   English

Efcore 2.2- where 子句在选择后运行并返回错误结果

[英]Efcore 2.2- where clause runs after selection and returns false results

I have this simple query:我有这个简单的查询:

Expression<Func<Tips, bool>> lastTipsPredicate = x => x.Status == (int)EnumGringo.LU_Status.active;

IQueryable<Tips> lastQueryBase(DbSet<Tips> t) => t.OrderByDescending(x => x.CreateDate).Take(6);
IEnumerable<Tips> latestTips = await base.GetAllByCondition(lastTipsPredicate, lastQueryBase);

This is my base repository:这是我的基本存储库:

public virtual async Task<IEnumerable<TEntity>> GetAllByCondition(Expression<Func<TEntity, bool>> predicate, Func<DbSet<TEntity>, IQueryable<TEntity>> baseQuery = null)
        {
            IQueryable<TEntity> q = context.Set<TEntity>();

            if (baseQuery != null)
            {
                q = baseQuery(context.Set<TEntity>());
            }

            return await q.Where(predicate).ToListAsync();
        }

This generate this sql query(From profiler):这将生成此 sql 查询(来自分析器):

exec sp_executesql N'SELECT [t].[ID], [t].[CreateDate], [t].[Description], [t].[InsertedByGringo], [t].[IsRecommended], [t].[IsSubscribe], [t].[LanguageType], [t].[SeoId], [t].[Slug], [t].[Status], [t].[Title], [t].[UserID], [t].[ViewCount]
FROM (
    SELECT TOP(@__p_0) [x].[ID], [x].[CreateDate], [x].[Description], [x].[InsertedByGringo], [x].[IsRecommended], [x].[IsSubscribe], [x].[LanguageType], [x].[SeoId], [x].[Slug], [x].[Status], [x].[Title], [x].[UserID], [x].[ViewCount]
    FROM [Tips] AS [x]
    ORDER BY [x].[CreateDate] DESC
) AS [t]
WHERE [t].[Status] = 1',N'@__p_0 int',@__p_0=6

Which returns only 5 records and not 6 as I expected, 1 record is filtered out because it has status!=1.它只返回 5 条记录,而不是我预期的 6 条记录,有 1 条记录被过滤掉,因为它有状态!=1。

While this query is the correct one and returns the last 6 records:虽然此查询是正确的并返回最后 6 条记录:

SELECT top 6 [t].[ID], [t].[CreateDate], [t].[Description], [t].[InsertedByGringo], [t].[IsRecommended], [t].[IsSubscribe], [t].[LanguageType], [t].[SeoId], [t].[Slug], [t].[Status], [t].[Title], [t].[UserID], [t].[ViewCount]
FROM Tips as [t]
WHERE [t].[Status] = 1
ORDER BY [t].CreateDate DESC

How can I generate the second query instead of the first one?如何生成第二个查询而不是第一个查询?

Efcore 2.2- where clause runs after selection and returns false results Efcore 2.2- where 子句在选择后运行并返回错误结果

It's neither EF Core nor LINQ problem, but the way your repository method builds the LINQ query.这既不是 EF Core 也不是 LINQ 问题,而是您的存储库方法构建 LINQ 查询的方式。

If you want to apply filtering ( Where ) first and then optionally the rest, then you should change the baseQuery func input type from DbSet<TEntity> to IQueryable<TEntity> , and the implementation as follows:如果您想先应用过滤( Where ),然后可选地应用其余部分,那么您应该将baseQuery func 输入类型从DbSet<TEntity>更改为IQueryable<TEntity> ,实现如下:

public virtual async Task<IEnumerable<TEntity>> GetAllByCondition(
    Expression<Func<TEntity, bool>> predicate,
    Func<IQueryable<TEntity>, IQueryable<TEntity>> baseQuery = null)
{
    var q = context.Set<TEntity>()
        .Where(predicate); // <-- (1)

    if (baseQuery != null)
        q = baseQuery(q); // <-- (2)

    return await q.ToListAsync();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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