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

问题描述

我有一个简单的查询

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class PizzaOrdering implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokelater(new PizzaOrdering());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("KRUSTY KRAB PIZZA");
        frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(getDeliveryMethodPanel(),BorderLayout.BEFORE_FirsT_LINE);
        frame.add(getUser@R_547_4045@ionPanel(),BorderLayout.CENTER);
        frame.add(getPizzaSizePanel(),BorderLayout.AFTER_LAST_LINE);
        frame.add(getMeatToppingsPanel(),BorderLayout.AFTER_LINE_ENDS);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel getDeliveryMethodPanel() {
        JPanel deliveryMethodPanel = new JPanel(new FlowLayout());
        ButtonGroup orderTypeGroup = new ButtonGroup();

        JRadioButton takeouTradioButton = 
                new JRadioButton("Take Out");
        orderTypeGroup.add(takeouTradioButton);
        deliveryMethodPanel.add(takeouTradioButton);

        JRadioButton deliveryRadioButton = 
                new JRadioButton("Delivery (Currently Unavailable)");
        deliveryRadioButton.setEnabled(false);
        orderTypeGroup.add(deliveryRadioButton);
        deliveryMethodPanel.add(deliveryRadioButton);

        return deliveryMethodPanel;
    }

    private JPanel getUser@R_547_4045@ionPanel() {
        JPanel user@R_547_4045@ionPanel = new JPanel(new GridBagLayout());
        user@R_547_404[email protected](
                BorderFactory.createEmptyBorder(5,5,5));

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(5,5);
        gbc.weightx = 1d;

        JLabel nameLabel = new JLabel("First Name:");
        user@R_547_404[email protected](nameLabel,gbc);

        gbc.gridx++;
        JTextField userNameField = new JTextField(20);
        user@R_547_404[email protected](userNameField,gbc);

        gbc.gridx = 0;
        gbc.gridy++;
        JLabel phoneNumberLabel = new JLabel("Phone Number:");
        user@R_547_404[email protected](phoneNumberLabel,gbc);

        gbc.gridx++;
        JTextField userPhoneNumberField = new JTextField(20);
        user@R_547_404[email protected](userPhoneNumberField,gbc);

        gbc.gridx = 0;
        gbc.gridy++;
        JLabel zipCodeLabel = new JLabel("Zip Code:");
        user@R_547_404[email protected](zipCodeLabel,gbc);

        gbc.gridx++;
        JTextField userZipCodeField = new JTextField(20);
        user@R_547_404[email protected](userZipCodeField,gbc);

        return user@R_547_4045@ionPanel;
    }

    private JPanel getPizzaSizePanel() {
        JPanel pizzaSizePanel = new JPanel(new FlowLayout());

        ButtonGroup sizeGroup = new ButtonGroup();
        JRadioButton smallRadioButton = new JRadioButton("Small");
        sizeGroup.add(smallRadioButton);
        pizzaSizePanel.add(smallRadioButton);

        JRadioButton mediumRadioButton = new JRadioButton("Medium");
        sizeGroup.add(mediumRadioButton);
        pizzaSizePanel.add(mediumRadioButton);

        JRadioButton largeRadioButton = new JRadioButton("Large");
        sizeGroup.add(largeRadioButton);
        pizzaSizePanel.add(largeRadioButton);

        return pizzaSizePanel;
    }

    private JPanel getMeatToppingsPanel() {
        JPanel meatToppingsPanel = new JPanel();
        meatToppingsPanel.setBorder(
                BorderFactory.createEmptyBorder(5,5));
        meatToppingsPanel.setLayout(new BoxLayout(
                meatToppingsPanel,BoxLayout.Y_AXIS));

        JCheckBox pepperoniCheckBox = new JCheckBox("Pepperoni");
        meatToppingsPanel.add(pepperoniCheckBox);
        
        JCheckBox meatballCheckBox = new JCheckBox("Meatball");
        meatToppingsPanel.add(meatballCheckBox);
        
        JCheckBox chickenCheckBox = new JCheckBox("Grilled Chicken");
        meatToppingsPanel.add(chickenCheckBox);
        
        JCheckBox sausageCheckBox = new JCheckBox("Italian Sausage");
        meatToppingsPanel.add(sausageCheckBox);
        
        JCheckBox baconCheckBox = new JCheckBox("Bacon");
        meatToppingsPanel.add(baconCheckBox);

        return meatToppingsPanel;
    }

}

这是我的基本存储库:

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

这将生成SQL查询(来自探查器):

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

仅返回5条记录,而不是我期望的6条记录,因为它具有状态,所以将过滤掉1条记录!= 1。

查询正确无误,并返回最后6条记录:

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

如何生成第二个查询而不是第一个查询

解决方法

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

这既不是EF Core也不是LINQ问题,而是您的存储库方法构建LINQ查询的方式。

如果您要先应用过滤(Where,然后再选择其余过滤,则应将baseQuery函数输入类型从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();
}